Можем ли мы использовать 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),

Это также ловит отступы в конце структуры. Кроме того, это делает утверждение более гибким в случае изменения элементов структуры во время обслуживания кода.

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