2013-07-24 6 views
31

В C/C++ (я предполагаю, что они одинаковы в этом отношении), если у меня есть следующие:структура выравнивания C/C++

struct S { 
    T a; 
    . 
    . 
    . 
} s; 

ли следующие гарантированно быть правдой?

(void*)&s == (void*)&s.a; 

Или, другими словами, есть любой вид гарантии, что не будет ни отступы перед тем первым членом?

+1

Это не то же самое в этом отношении –

+3

@MooingDuck: Ну, это зависит от того, что такое '...'. Для того же определения структуры C++ будет обрабатывать его так же, как структуры C (C всегда соответствуют стандарту C++ *). –

ответ

44

В C, да, это тот же адрес. Простой и понятный.


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

Наконец, если структура C++ состоит из типы макетов, не содержит базовых классов и виртуальных функций, и все члены имеют одинаковую видимость и, возможно, другие ограничения, которые я забыл, затем, он возвращается к правилам C и требует, чтобы первый член находился на том же адресе, что и сам объект.

§ 9,2/7

Класс стандартной компоновки является классом, который:
- не имеет нестатических элементов данных класса типа нестандартного типа макета (или массив таких типов) или справочник,
- не имеет виртуальные функции (10.3) и никаких виртуальных базовых классов (10.1),
- имеет тот же контроль доступа (пункт 11) для всех нестатических элементов данных,
- не имеет нестандартное- базовые классы макета,
- либо не имеет нестатических элементов данных в самом производном классе и не более одного базового класса с нестатическими членами данных или не имеет базовых классов с нестатическими элементами данных, а
- не имеет базовых классов того же типа, что и первый нестатический элемент данных ,

§ 9.2/20

указатель на объект структуры стандартной компоновки, соответствующим образом преобразованы с использованием reinterpret_cast, указывает на его начальном элементе (или, если этот член битовое поле, а затем в блок, в котором он находится) и наоборот. [Примечание. Таким образом, в рамках объекта структуры стандартного макета может быть указано неназванное заполнение, но не в его начале, по мере необходимости, для достижения соответствующего выравнивания. -end note]

+0

«класс стандартного макета» также известен как POD («простой старый тип данных»), и вы можете проверить его с помощью std :: is_pod. – marcinj

+10

@marcin_j: Нет. POD требует как * стандартного макета *, так и тривиальной конструкции/копирования/уничтожения *. Класс может иметь нестандартные конструкторы и деструкторы и другие специальные элементы и по-прежнему быть * стандартным макетом *. –

+0

спасибо за разъяснение, я вижу, что можно использовать std :: is_standard_layout , чтобы проверить правильность такого сравнения. – marcinj

16

Да, это так.

Гарантируется отсутствие прокладки перед первым элементом структуры в C и на C++ (если это POD).

С цитатой:

(С11, 6.7.2.1p15) «Там может быть неназванной обивка внутри объекта структуры, но не в его начале.»

C++ цитата:

(C++ 11, 9.2p20) «Там может быть поэтому неназванная обивка внутри объекта структуры стандартного макета, но не в ее начале, по мере необходимости для достижения соответствующей выравнивание "

+6

В C++ это гарантируется только в том случае, если это POD. –

+0

@ н.м. добавлена ​​цитата для C++ и упоминание для POD. Спасибо – ouah

+0

@ n.m. Если что такое POD? Строка 'S' или член' T'? – baruch

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

  • Нет связанных вопросов^_^