Выравнивание структуры C/C++

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

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

Гарантируется ли следующее?

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

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

2 ответа

Решение

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


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

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

§ 9.2 / 7

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

§ 9.2 / 20

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

Да, это.

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

С цитатой:

(C11, 6.7.2.1p15) "В объекте структуры может быть безымянный отступ, но не в его начале".

C++ цитата:

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

Другие вопросы по тегам