Как уже упоминали другие, это не является частью стандарта и оставлено на усмотрение компилятора так, как он считает нужным для рассматриваемого процессора. Например, VC может легко реализовать другие требования к выравниванию для процессора ARM, чем для процессоров x86.
Microsoft VC реализует то, что обычно называется естественным выравниванием, вплоть до размера, указанного в директиве #pragma pack или параметре командной строки / 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 (т.е. для CE).