2015-01-29 5 views
0

Я тестировал выравнивание классов и обнаружил странное поведение. Я протестировал его с настройкой компилятора VS2012 4 и 8 байт, но в каждом случае вывод такой же.Вопрос о выравнивании класса

class Alignemnt{ 
public: 
    Alignemnt():a(){} 
    int a; 
}; 

class Alignemnt_1{ 
public: 
    int a; 
    char array[2]; 
}; 

class Alignemnt_2{ 
public: 
    int a; 
    char array[2]; 
    int x; 
}; 

std::cout << "Sizeof(Alignemnt) :" <<sizeof(Alignemnt) << std::endl; 
std::cout << "Sizeof(Alignemnt_1) :" <<sizeof(Alignemnt_1) << std::endl; 
std::cout << "Sizeof(Alignemnt_2) :" <<sizeof(Alignemnt_2) << std::endl; 

Каждый выход время:

Sizeof(Alignemnt) : 4 

Sizeof(Alignemnt_1) : 8 

Sizeof(Alignemnt_2) : 12 

Я думаю, размер Alignemnt_2 должен быть 16 байт.

+1

Итак, каков ваш вопрос? Мне кажется, что компилятор работает отлично? –

+0

Я думаю, размер Alignemnt_2 должен быть 16 байт. – CrazyC

+0

int обычно будет выровняться по 4 байт. char [2] - всего 2 байтовый объект. Вы получаете размер в 12 байт, потому что первый int занимает 4 байта, второй объект занимает 2 байта, а третий - 4 байт. – Charlie

ответ

0

Выравнивание не должно изменять размер вашего объекта, только начальный адрес объектов. Например, 8-байтовый выровненный объект может иметь адрес 0x100000 или 0x100008, или действительно любой адрес, заканчивающийся на 0 или 8, если он записан в шестнадцатеричном формате, но не 0x100004.

+0

Я не согласен с этим. выравнивание связано с заполнением, которое изменяет размер объекта. – CrazyC

+0

Кроме того, размер объекта будет кратным его выравниванию. –

+0

Да. @ Gha..st. Выравнивание всегда дает размер объекта нескольким параметрам. Здесь я сделал это 8 байт, поэтому вместо 12 это должно быть 16. – CrazyC

2

Я предполагаю, что вы имеете в виду /Zp переключатель, который позволяет контролировать максимальную STRUCT выравнивание члена:

При указании этой опции, каждый член структуры после первого хранится на любом размере тип элемента или n-байтовые границы (где n равно 1, 2, 4, 8 или 16), в зависимости от того, что меньше.

Поскольку вы не используете член структуры с выравниванием более 4 байт (sizeof(int) и alignof(int) одновременно 4), все настройки 4 байта и выше приведут к точно такому же поведению.

Если вы хотите, чтобы указать точное выравнивания элемента структуры, следует использовать стандартный C++ alignas, который позволяет определить точное выравнивание члена предполагается иметь (VS 2012 должен поддерживать его IIRC).

See the result of using alignas.

0

Номер

ALIGMENT 2 отлично.

У вас есть 2 символа рядом друг с другом, это означает, что вы используете 2 из 4 байтов. Упаковка будет выровнять его до 4 байтов, а затем вы получите 4 + 4 +4.

Если вы хотите закончить до 16 вы можете попробовать следующее заявление:

{ 
     char a; 
     int b; 
     char c; 
     int d; 
} 
+0

@CrazyC Любая причина для downvote? Есть ли что-то, что я сказал не так? или вы просто как downvoting ради downvoting? – MichaelCMS

+0

Я не дал голоса, но исправил его как ноль. – CrazyC

+0

@CrazyC ах, извините. Я думал, что ты проиграл. Тем не менее, я все равно хотел бы знать, почему downvoter был downvoted ... – MichaelCMS

Смежные вопросы