Страницы

Поиск по вопросам

Показаны сообщения с ярлыком выравнивание. Показать все сообщения
Показаны сообщения с ярлыком выравнивание. Показать все сообщения

четверг, 2 апреля 2020 г.

Не понимаю поведения класса при добавлении к нему ul

#html #css #css3 #выравнивание #ul

                    
В заголовке сформулировал вопрос.
 Пример  кода - jsfiddle



body {
  background-color: lavender;
}

.icons_main_class {
  list-style: none;
  margin: 0;
  padding: 0;
  margin-right: 10px;
  text-align: right;
}

.icons_main_class li {
  background-image: url(https://image.flaticon.com/sprites/share/packs/174834-social-media-logos.png);
  display: inline-block;
  padding: 0;
  margin: 0;
  width: 32px;
  height: 32px;
  background-size: 13rem;
  border-radius: 5px;
}

.social1 {
  background-position: 20% -0.3%;
}

.social2 {
  background-position: 40% 0;
}

.social3 {
  background-position: 99% 0;
}
Есть вот такой код, где я спрайтами попытался сделать что-то типа кнопок соц сетей и вроде бы все работает как надо. Но вот меня мучит один вопрос (реально хочу знать и понимать), если к классу .icons_main_class добавить ul (то есть так - .icons_main_class ul {...}) , то почему-то перестает работать text-align. Как я понимаю и меню эта слетает в исходное положение (left). И вот мне интересно почему, ведь мы по сути обращаемся к классу, который содержится в том же теге ul, но если его прописать, то случается такая фигня, расскажите пожалуйста в чем дело и почему так происходит и еще когда добавляем этот ul то слева откуда то появляется margin, хотя в свойствах его нет, тоже непонятный момент.


Ответы

Ответ 1



ul.icons_main_class { list-style: none; background: red; } /* Потому, что ты не правильно последовательность селекторов прописываешь*/ /* ты говоришь, возьми тег ul который в каком то блоке классом icons_main_class2 */ /* и пропиши ему правила ниже, а такой последовательности селекторов нет*/ .icons_main_class2 ul { list-style: none; background: red; }
  • social1
  • social1


воскресенье, 2 февраля 2020 г.

Выровнять ссылки по центру с фиксированной шириной

#html #выравнивание


Ломаю голову над проблемой, есть блок скажем шириной 900px в него нужно поместить
кнопки шириной скажем 200px разместить их по центру ну и придать красивостей. делаю
с помощью такого кода








но ссылки расползаются по всему пространству дива. Если у кого нибудь есть варианты
как решить подобную проблему подскажите плз
    


Ответы

Ответ 1



добавляешь стиль, .buttons { text-align: center; } и твои ссылки выравниваются по центру

Ответ 2



text-align: center ?

Ответ 3



.buttons{ width: 500px; border: 1px solid gray; display: flex; flex-direction: column; align-items: center; } Как сделать подобное с помощью Flex.

Ответ 4



ul{ display:table; margin:auto; } ul li{ display:table-cell; width:20%; text-align:center; }

суббота, 1 февраля 2020 г.

Безопасно ли получать адрес члена невыровненной структуры

#cpp #c #выравнивание


Меня интересует следующий вопрос:

struct S
{
    // ...
    int i;
};

void f(uint8_t *_buf, size_t _offset)
{
    uint8_t *pu = _buf + _offset;
    S *ps = (S*)pu;
    int *pi = &(ps->i);// UB or not UB?

    int i;
    memcpy(&i, pi, sizeof(int));
}


У нас есть буфер байтов и смещение. По указанному смещению в буфере лежит объект
типа S. Этот объект имеет неверное выравнивание, как и поле i этого объекта.

Меня интересует, можно ли получить адрес поля i описанным образом, чтобы потом считать
int с указанного адреса безопасным способом - по одному байту или при помощи memcpy(). 
    


Ответы

Ответ 1



C99 6.3.2.3/7 A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. *Otherwise... Вольный перевод: Указатель на объект или неполный тип может быть преобразован в указатель на другой объект или неполный тип. Если результирующий указатель не выровнен корректно для типа, на который он будет указывать, поведение неопределено. Иначе... Т.е. со строгих слов стандарта Си получение любого не выровненного указателя, не зависимо от того, будет ли по нему доступ к памяти или нет — UB.

Ответ 2



Для этого будет достаточно взять смещение этого поля от начала структуры без каких-либо промежуточных указателей (подразумевается, что структура является standard layout type): ::std::memcpy(::std::addressof(i), _buf + _offset + offsetof(S, i), sizeof(i)); Что касается попытки преобразования указателя на объект с менее строгим выравниванием к указателю на объект с более строгим выравниванием, то в С++ поведение не специфицировано (то бишь задается реализацией): 8.5.1.10 Reinterpret cast [expr.reinterpret.cast] 7 An object pointer can be explicitly converted to an object pointer of a different type. 73 When a prvalue v of object pointer type is converted to the object pointer type “pointer to cv T ”, the result is static_cast(static_cast(v)). [Note: Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. —end note ] 8.5.1.9 Static cast [expr.static.cast] 13 A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T”, where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an object a, and there is an object b of type T (ignoring cv-qualification) that is pointer-interconvertible (6.7.2) with a, the result is a pointer to b. Otherwise, the pointer value is unchanged by the conversion. Но вот использовать полученный указатель на структуру (даже если реализация правильно производит преобразование адреса) для получения указателя на поле этой структуры уже будет неопределенным поведением.

пятница, 20 декабря 2019 г.

Оптимизация выравнивания компиляторами

#cpp #c #выравнивание


Следующие структуры имеют одинаковые поля.

struct A {
    char a;
    char c;
    double b;
};

struct B {
    char a;
    double b;
    char c;
};


Но их размер будет отличаться. Как именно - зависит от архитектуры. У меня это 16
и 28 байт соответственно. 

Почему так происходит - я понимаю. Вопрос в том, почему компиляторы не делают такой,
казалось бы, банальной и очевидной оптимизации? Проверял на minGW и clang
    


Ответы

Ответ 1



Это скорее традиция, чем необходимость. Язык мог бы дать разработчику средства управлять точным выравниванием, и разрешать или запрещать перестановку членов структуры при необходимости. В начале истории языка количество байт padding'а было очевидно, т. к. архитектура была известна разработчику. Это позволяло определять бинарные форматы таким образом, что лэйаут байт в файле или отображение регистров устройства прямо соответствует расположению полей структуры в памяти. Таким образом, работу с файлами и устройствами можно организовывать через blitting, без копирования и разбора. Чтобы гарантировать отсутствие сюрпризов от оптимизатора, стандарт C запрещает перестановку полей. Ссылка на стандарт, параграф 6.7.2.1/15: Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning. Поскольку сейчас существует довольно много кода, который опирается на этот факт, ослаблять требования комитет по стандартизации будет вряд ли. Тем не менее, в качестве расширения языка GCC умеет переставлять поля структур, если его об этом хорошо попросить. (В последних официальных версиях эта фича выключена, но можно собрать себе GCC из экспериментальной ветки.)

Ответ 2



C++ произошел от языка C, который приближен к архитектуре компьютеров. Фактически язык C считается языком ассемблера среди языков высокого уровня. Поэтому порядок расположения членов данных класса порой очень важен, так как класс может отображаться на физическую структуру данных компьютера. Компилятор самовольно не меняет расположение членов в классе, которые имеют один и тот же класс доступа тем более как в стандартно-размещаемых классах. Поэтому об оптимизации должен позаботиться программист, если для него порядок расположения членов данных в структуре не важен, а важно их более компактное размещение. Если есть возможность, то всегда старайтесь члены данных структуры с более строгим выравниванием помещать в начало структуры

Ответ 3



Думаю, для соответствия интерфейсам. Аналогично аппаратному соответствию, описанному в других ответах, можно упомянуть и программные интерфейсы. Интерфейс подразумевает одинаковую трактовку параметров с обеих сторон. Несоответствие порядка и типа аргументов легко отследить, пока обе стороны (передающая аргументы и принимающая) транслируются одним компилятором. Но если передающая и принимающая функции не входят в состав одного модуля? К примеру, некоторые функции WinAPI принимают параметрами структуры. Если бы каждый компилятор по своему усмотрению мог бы переставлять поля структур, то передача структур между программами и библиотеками была бы похожей на лотерею. Ведь если компилятор библиотеки и компилятор использующей её программы применили бы разный алгоритм оптимизации (переставили бы поля структур в разном порядке), то по ожидаемому смещению программа иногда получала бы значения совершенно других полей.

суббота, 30 ноября 2019 г.

О чём говорит предупреждение о выравнивании данных?

#cpp #память #gcc #выравнивание


При компиляции такого кода для ARM

char* c = 0;
int* p = reinterpret_cast(c);


GCC выводит предупреждение


  cast from ‘char*’ to ‘int*’ increases required alignment of target type


Какими последствиями чревато подобное применение reinterpret_cast для типов с разными
требованиями по выравниванию? Почему такое предупреждение возникает не на всех платформах?
О чём вообще это, нужно ли как-то исправлять?

https://godbolt.org/g/VGDK3w

По ссылке выше вы увидете попытку компиляции такого кода для процессоров x86_64 и
ARM. Несмотря на одинаковые флаги компилятора, результат получился разным.
    


Ответы

Ответ 1



Поведение reinterpret_cast в этом случае зависит от платформы. Начиная с С++11 поведение такого преобразования определяется как int* p = static_cast(static_cast(c)); и результат будет зависеть от поведения внешнего static_cast. Поведение static_cast из void * в объектный указательный тип является неспецифицированным, если исходный void * адрес не удовлетворяет требованиям выравнивания целевого типа. На одной платформе приведение типа от указателя с более расслабленными требованиями выравнивания к указателю с более строгими требованиями выравнивания может привести к потере оригинального адресного значения, т.е. компилятор и/или аппаратура насильно выравняют указатель. На другой платформе адресное значение указателя сохранится, но при попытке доступа через невыровненный указатель программа будет аварийно остановлена. На третьей платформе адресное значение указателя сохранится, но при доступе через невыровненный указатель такой доступ будет производиться успешно, но менее эффективно. На четвертой платформе не будет вообще никаких негативных последствий. Предупреждение о выравнивании данных может либо говорить том, что подобные проблемы могут иметь место на вашей платформе, либо просто являться педантичным "предупреждением портабельности", т.е. говорить том, ваш код может вести себя по-другому на других платформах.

воскресенье, 9 июня 2019 г.

Не понимаю поведения класса при добавлении к нему ul

В заголовке сформулировал вопрос. Пример кода - jsfiddle
body { background-color: lavender; } .icons_main_class { list-style: none; margin: 0; padding: 0; margin-right: 10px; text-align: right; } .icons_main_class li { background-image: url(https://image.flaticon.com/sprites/share/packs/174834-social-media-logos.png); display: inline-block; padding: 0; margin: 0; width: 32px; height: 32px; background-size: 13rem; border-radius: 5px; } .social1 { background-position: 20% -0.3%; } .social2 { background-position: 40% 0; } .social3 { background-position: 99% 0; }


Есть вот такой код, где я спрайтами попытался сделать что-то типа кнопок соц сетей и вроде бы все работает как надо. Но вот меня мучит один вопрос (реально хочу знать и понимать), если к классу .icons_main_class добавить ul (то есть так - .icons_main_class ul {...}) , то почему-то перестает работать text-align. Как я понимаю и меню эта слетает в исходное положение (left). И вот мне интересно почему, ведь мы по сути обращаемся к классу, который содержится в том же теге ul, но если его прописать, то случается такая фигня, расскажите пожалуйста в чем дело и почему так происходит и еще когда добавляем этот ul то слева откуда то появляется margin, хотя в свойствах его нет, тоже непонятный момент.


Ответ

ul.icons_main_class { list-style: none; background: red; } /* Потому, что ты не правильно последовательность селекторов прописываешь*/ /* ты говоришь, возьми тег ul который в каком то блоке классом icons_main_class2 */ /* и пропиши ему правила ниже, а такой последовательности селекторов нет*/ .icons_main_class2 ul { list-style: none; background: red; }

  • social1
  • social1

воскресенье, 7 апреля 2019 г.

Выровнять ссылки по центру с фиксированной шириной

Ломаю голову над проблемой, есть блок скажем шириной 900px в него нужно поместить кнопки шириной скажем 200px разместить их по центру ну и придать красивостей. делаю с помощью такого кода


но ссылки расползаются по всему пространству дива. Если у кого нибудь есть варианты как решить подобную проблему подскажите плз


Ответ

добавляешь стиль,
.buttons { text-align: center; }
и твои ссылки выравниваются по центру