В c / c ++ (я предполагаю, что они одинаковы в этом отношении), если у меня есть следующее:
struct S {
T a;
.
.
.
} s;
Гарантируется ли следующее?
(void*)&s == (void*)&s.a;
Или, другими словами, есть ли какая-либо гарантия, что не будет заполнения до первый член?
В Си, да, это один и тот же адрес. Просто и понятно.
В 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) «Следовательно, в объекте структуры стандартной компоновки может быть безымянный отступ, но не в его начале, что необходимо для достижения надлежащего выравнивания»