gcc / clang размещает поля производной структуры в отступах базовой структуры [duplicate]
На этот вопрос уже есть ответ:
Стандартная компоновка и обивка хвоста 5 ответовМеня смущает то, как gcc и clang выстраивают структуры, когда задействованы как padding, так и наследование. Вот пример программы:
#include <string.h>
#include <stdio.h>
struct A
{
void* m_a;
};
struct B: A
{
void* m_b1;
char m_b2;
};
struct B2
{
void* m_a;
void* m_b1;
char m_b2;
};
struct C: B
{
short m_c;
};
struct C2: B2
{
short m_c;
};
int main ()
{
C c;
memset (&c, 0, sizeof (C));
memset ((B*) &c, -1, sizeof (B));
printf (
"c.m_c = %d; sizeof (A) = %d sizeof (B) = %d sizeof (C) = %d\n",
c.m_c, sizeof (A), sizeof (B), sizeof (C)
);
C2 c2;
memset (&c2, 0, sizeof (C2));
memset ((B2*) &c2, -1, sizeof (B2));
printf (
"c2.m_c = %d; sizeof (A) = %d sizeof (B2) = %d sizeof (C2) = %d\n",
c2.m_c, sizeof (A), sizeof (B2), sizeof (C2)
);
return 0;
}
Выход
$ ./a.out
c.m_c = -1; sizeof (A) = 8 sizeof (B) = 24 sizeof (C) = 24
c2.m_c = 0; sizeof (A) = 8 sizeof (B2) = 24 sizeof (C2) = 32
Структуры C1 и C2 расположены по-разному. В C1 m_c размещается в отступе структуры B1 и поэтому перезаписывается 2-м memset (); с C2 этого не происходит.
Используются компиляторы:
$ clang --version
Ubuntu clang version 3.3-16ubuntu1 (branches/release_33) (based on LLVM 3.3)
Target: x86_64-pc-linux-gnu
Thread model: posix
$ c++ --version
c++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
То же самое происходит с опцией -m32 (очевидно, что размеры выходных данных будут другими).
В обеих версиях компилятора Microsoft Visual Studio 2010 C ++ для x86 и x86_64 такой проблемы нет (т. Е. Они одинаково выкладывают структуры С1 и С2)
Если это не ошибка, и она задумана, то мои вопросы:
Каковы точные правила для выделения или не выделения полей производной структуры в отступах (например, почему это не происходит с C2?) есть ли способ переопределить это поведение с помощью переключателей / атрибутов (т.е. выложить так же, как MSVC)?Заранее спасибо
Владимир