Для sizeof оператора действительно ли возможно когда-либо возвратиться 0 (нуль) в C или C++? Если это возможно, это корректно с точки зрения стандартов?
В C ++ пустой класс или структура по определению имеет размер sizeof
как минимум 1. Согласно стандарту C ++, 9/3 «Классы»: «Полные объекты и подобъекты-члены типа класса должны иметь ненулевой размер»
. В C пустая структура не разрешена, за исключением случаев расширения (или недостатка компилятора) .
Это следствие грамматики (которая требует, чтобы что-то было внутри фигурных скобок) вместе с этим предложением из 6.7.2.1/7 «Спецификаторы структуры и объединения»: «Если список-декларации-структуры не содержит именованных членов , поведение не определено ".
Если структура нулевого размера разрешена, то это расширение языка (или ошибка компилятора). Например, в GCC расширение описано в «Структуры без членов» , где говорится:
GCC разрешает структуре C не иметь членов:
struct empty { };
Структура будет иметь нулевой размер. В C ++ пустые структуры являются частью языка. G ++ обрабатывает пустые структуры, как если бы они имели единственный член типа
char
.
Пустые структуры, как isbadawi упоминает . Также gcc позволяет массивов нулевого размера :
int a[0];
sizeof(a);
РЕДАКТИРОВАТЬ: Увидев ссылку MSDN, я попробовал пустую структуру в VS2005, и sizeof вернул 1. Я не уверен, что это ошибка VS или спецификация в некоторой степени гибка в отношении подобных вещей
Я думаю, что он никогда не возвращает 0 в c, пустые структуры не допускаются
Каждый объект в 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
) {{1 }} - это количество байтов в объекте, включая любые отступы, необходимые для превращения мозаики объекта в массив
Поскольку байт заполнения должен быть добавлен к "пустому" объекту по порядку поэтому для работы с массивом sizeof ()
должен возвращать значение не менее 1 для любого допустимого ввода.
Изменить:
Раздел A8.3 спецификации C вызывает структуру без списка членов неполный тип , а в определении sizeof
конкретно указано (с выделением добавлено):
Оператор (sizeof) нельзя применять к операнду типа функции , или неполного типа , или к битовому полю .
Это означало бы, что использование sizeof
в пустой структуре было бы столь же недействительным, как и использование его в типе данных, который не был определен. Если ваш компилятор допускает использование пустых структур, имейте в виду, что использование на них sizeof
запрещено согласно спецификации C. Если ваш компилятор все равно позволяет это делать, поймите, что это нестандартное поведение, которое не будет работать на всех компиляторах; не полагайтесь на такое поведение.
Изменить: См. Также эту запись в FAQ Бьярна Страуструпа.
sizeof
никогда не возвращает 0
в C и C ++. Каждый раз, когда вы видите, что sizeof
оценивается как 0
, это ошибка / сбой / расширение определенного компилятора, не имеющего ничего общего с языком.
На мой взгляд, лучше, чтобы sizeof возвращал 0 для структуры размера 0 (в духе c). но тогда программист должен быть осторожен, когда он берет размер пустой структуры.
, но это может вызвать проблему. когда массив таких структур определен, тогда
& arr [1] == & arr [2] == & arr [0]
, что заставляет их проигрывать их личности.
Полагаю, это не дает прямого ответа на ваш вопрос, возможно это или нет. ну, это может быть возможно в зависимости от компилятора. (как сказано в ответе Майкла выше).
Вот тест, где sizeof дает 0
#include <stdio.h>
void func(int i)
{
int vla[i];
printf ("%u\n",(unsigned)sizeof vla);
}
int main(void)
{
func(0);
return 0;
}