Можем ли мы использовать static_assert для обнаружения заполнения в структуре?
Это продолжение этого другого вопроса
Я пытался установить во время компиляции, добавила ли конкретная реализация неназванный отступ внутри структуры. Конкретная реализация, такая как gcc, позволяет использовать прагмы для управления заполнением и выравниванием в структурах, но за счет совместимости с другими реализациями. Как оба static_assert
а также offset_of
требуются черновой вариант n1570 для C11, я хотел использовать их, чтобы увидеть, использует ли реализация заполнение между членами.
Вот соответствующая часть кода (полный код в указанном вопросе):
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
struct quad {
int x;
int y;
int z;
int t;
};
int main() {
// ensure members are consecutive (note 1)
static_assert(offsetof(struct quad, t) == 3 * sizeof(int),
"unexpected padding in quad struct");
struct quad q;
...
Как 6.7.2.1 Спецификаторы структуры и объединения § 15 гласит:
Внутри объекта структуры члены без битовых полей и блоки, в которых находятся битовые поля, имеют адреса, которые увеличиваются в порядке их объявления. Указатель на объект структуры, соответствующим образом преобразованный, указывает на его начальный элемент (или, если этот элемент является битовым полем, то на модуль, в котором он находится), и наоборот. Внутри объекта структуры может быть безымянный отступ, но не в его начале.
Я предположил, что если бы смещение элемента в структуре было суммой размеров элементов, объявленных до него, то между этими элементами не могло бы быть заполнения, и они должны располагаться последовательно, образуя массив, если они были одного типа.
Вопрос в том, является ли приведенное выше предположение неправильным, и почему оно таково (что позволяют подумать комментарии к контрольному вопросу)?
1 ответ
Теоретически может быть заполнение в конце структуры после t
, который ваше утверждение не улавливает (что может или не может быть предназначено). Ваше предположение в противном случае правильно, и это совершенно нормально использовать offsetof
а также static_assert
, чтобы обнаружить заполнение в любом месте между переменными-членами.
Лучшая альтернатива может быть:
static_assert( offsetof(struct quad, t) == sizeof(struct quad)-sizeof(int),
Это также ловит отступы в конце структуры. Кроме того, это делает утверждение более гибким в случае изменения элементов структуры во время обслуживания кода.