Вопрос

Например, если я объявлю длинную переменную, могу ли я предположить, что она всегда будет выровнена по границе «sizeof(long)»?Так утверждается в онлайн-справке Microsoft Visual C++, но является ли это стандартным поведением?

еще немного информации:

а.Можно явно создать смещенное целое число (*bar):

чар фу[5]

int * bar = (int *)(&foo[1]);

б.Судя по всему, #pragma package() влияет только на структуры, классы и объединения.

в.В документации MSVC указано, что типы POD привязаны к соответствующим размерам (но всегда ли это или по умолчанию, и является ли это стандартным поведением, я не знаю)

Это было полезно?

Решение

Как уже отмечали другие, это не является частью стандарта и остается на усмотрение компилятора реализовать его так, как он считает целесообразным для рассматриваемого процессора.Например, VC может легко реализовать другие требования к выравниванию для процессора ARM, чем для процессоров x86.

Microsoft VC реализует так называемое естественное выравнивание до размера, указанного директивой пакета #pragma или параметром командной строки /Zp.Это означает, что, например, любой тип POD размером меньше или равный 8 байтам будет выровнен по его размеру.Все, что больше, будет выровнено по границе 8 байт.

Если важно контролировать выравнивание для разных процессоров и разных компиляторов, вы можете использовать размер упаковки, равный 1, и дополнить свои структуры.

#pragma pack(push)
#pragma pack(1)    
struct Example
{
   short data1;     // offset 0
   short padding1;  // offset 2
   long data2;      // offset 4
};
#pragma pack(pop)

В этом коде padding1 переменная существует только для того, чтобы убедиться, что data2 естественно выровнена.

Ответ на:

Да, это может легко привести к смещению данных.На процессоре x86 это совсем не повредит.На других процессорах это может привести к сбою или очень медленному выполнению.Например, процессор Alpha выдаст исключение процессора, которое будет перехвачено ОС.Затем ОС проверит инструкцию и выполнит работу, необходимую для обработки невыровненных данных.Затем выполнение продолжается.А __unaligned Ключевое слово может использоваться в VC для обозначения невыровненного доступа для программ, отличных от x86 (т.е.сила).

Другие советы

По умолчанию да.Однако его можно изменить с помощью Pack() #pragma.

Я не верю, что стандарт C++ предъявляет какие-либо требования в этом отношении и оставляет это на усмотрение реализации.

C и C++ не требуют какого-либо выравнивания.Но естественное выравнивание явно предпочтительнее для x86. необходимый большинством других архитектур ЦП, и компиляторы обычно делают все возможное, чтобы процессоры были довольны.Таким образом, на практике вы не увидите, как компилятор генерирует невыровненные данные, если вы действительно не повернете ему руку.

Да, все типы всегда соответствуют как минимум своим требованиям выравнивания.

Как же может быть иначе?

Но обратите внимание, что sizeof() типа — это не то же самое, что его выравнивание.

Чтобы определить требования к выравниванию типа, можно использовать следующий макрос:

#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )

Зависит от компилятора, прагм и уровня оптимизации.С помощью современных компиляторов вы также можете выбрать оптимизацию времени или пространства, что также может изменить выравнивание типов.

Обычно это происходит потому, что чтение/запись в него происходит быстрее.Но почти в каждом компиляторе есть переключатель, позволяющий отключить это.В gcc это -злокачественно-???.В агрегатах они обычно выравниваются и имеют размер в зависимости от требований к выравниванию каждого элемента внутри.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top