Каждый объект в C должен иметь уникальный адрес. Иными словами, адрес должен содержать не более одного объекта данного типа (чтобы разыменование указателя работало). При этом рассмотрим «пустую» структуру:
struct emptyStruct {};
и, более конкретно, их массив:
struct emptyStruct array[10];
struct emptyStruct* ptr = &array[0];
Если объекты действительно были пустыми (то есть, если sizeof(struct emptyStruct) == 0
), то ptr++ ==> (void*)ptr + sizeof(struct emptyStruct) ==> ptr
, что не имеет смысла. К какому объекту тогда относится *ptr
, ptr[0]
или ptr[1]
?
Даже если структура не имеет содержимого, компилятор должен обрабатывать ее так, как если бы она была длиной в один байт, чтобы поддерживать принцип «один адрес, один объект».
Спецификация языка C (раздел A7.4.8) формулирует это требование как
применительно к конструкции или объединению,
результат (оператора sizeof
)
количество байтов в объекте,
включая любые отступы, необходимые для
объект мозаичный массив
Поскольку байт заполнения должен быть добавлен к «пустому» объекту, чтобы он работал в массиве, sizeof()
должен поэтому возвращать значение по крайней мере 1 для любого допустимого ввода.
Edit:
Раздел A8.3 спецификации C вызывает структуру без списка членов неполный тип , а определение sizeof
специально гласит (с добавлением акцента):
Оператор (sizeof) не может быть
применяется к операнду функции
типа, или неполного типа , или
битовое поле.
Это будет означать, что использование sizeof
для пустой структуры будет столь же недействительным, как и использование его для типа данных, который не был определен. Если ваш компилятор допускает использование пустых структур, имейте в виду, что использование sizeof
на них не разрешено согласно спецификации C. Если ваш компилятор все равно позволяет вам это делать, помните, что это нестандартное поведение, которое не будет работать на всех компиляторах; не полагайтесь на это поведение.
Редактировать: См. Также эту запись в FAQ Бьярна Страуструпа.