Можно resize 0 (ноль)

Возможно ли, чтобы оператор sizeof когда-либо возвращал 0 (ноль) в C или C ++? Если это возможно, правильно ли это с точки зрения стандартов?

В C ++ пустой class или структура имеет sizeof по крайней мере 1 по определению. Из стандарта C ++ 9/3 «Классы»: «Завершенные объекты и субобъекты членов типа classа должны иметь ненулевой размер».

В C пустая структура не разрешена, за исключением расширения (или недостатка в компиляторе).

Это является следствием грамматики (которая требует наличия чего-то внутри фигурных скобок) вместе с этим предложением из 6.7.2.1/7 «Спецификации структуры и объединения»: «Если в списке struct-declaration-list нет именованных членов, поведение не определено ».

Если разрешена структура нулевого размера, то это расширение языка (или недостаток в компиляторе). Например, в GCC расширение описано в разделе «Структуры без членов» , в котором говорится:

GCC разрешает структуре C не иметь членов:

  struct empty { }; 

Структура будет иметь нулевой размер. В C ++ пустые структуры являются частью языка. G ++ обрабатывает пустые структуры, как если бы у них был единственный член типа char .

sizeof никогда не возвращает 0 в C и на C ++. Каждый раз, когда вы оцениваете значение sizeof в 0 это ошибка / сбой / расширение конкретного компилятора, который не имеет никакого отношения к языку.

Каждый объект в 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 для любого допустимого ввода.

Изменить: Раздел A8.3 спецификации C вызывает структуру без списка членов неполного типа и определение sizeof конкретных состояний (с добавлением акцента):

Оператор (sizeof) не может быть применен к операнду типа функции или неполного типа или к битовому полю.

Это подразумевает, что использование sizeof в пустой структуре было бы столь же недействительным, как использование его по типу данных, который не был определен. Если ваш компилятор позволяет использовать пустые структуры, имейте в виду, что использование sizeof на них не допускается в соответствии с спецификацией C. Если ваш компилятор позволяет вам это сделать, поймите, что это нестандартное поведение, которое не будет работать на всех компиляторах; не полагайтесь на это поведение.

Редактировать: Смотрите также эту запись в FAQ Bjarne Stroustrup.

Пустые структуры, как упоминает Исбадави . Также gcc позволяет массивы размером 0 :

 int a[0]; sizeof(a); 

EDIT: увидев ссылку MSDN, я попробовал пустую структуру в VS2005, и sizeof вернул 1. Я не уверен, что это ошибка VS или если спецификация настолько гибка в отношении такого рода вещей

на мой взгляд, лучше, что sizeof возвращает 0 для структуры размера 0 (в духе с). но тогда программист должен быть осторожным, когда берет sizeof пустой структуры.

но это может вызвать проблемы. когда массив таких структур определен, то

& arr [1] == & arr [2] == & arr [0]

что заставляет их терять свою идентичность.

Я думаю, это напрямую не отвечает на ваш вопрос, возможно ли это или нет. хорошо, что может быть возможно в зависимости от компилятора. (как сказано в ответе Майкла выше).

 typedef struct { int : 0; } x; x x1; x x2; 

Под MSVC 2010 (/ Za / Wall):

 sizeof(x) == 4 &x1 != &x2 

В разделе GCC (-ansi -pedantic -Wall):

 sizeof(x) == 0 &x1 != &x2 

т.е. хотя в GCC он имеет нулевой размер, экземпляры структуры имеют разные адреса.

ANSI C (C89 и C99 – я не смотрел на C ++) говорит: «Можно однозначно выразить адрес каждого отдельного байта объекта». Это кажется неоднозначным в случае объекта с нулевым размером, поскольку он, возможно, не имеет байтов.

Изменить: «Объявление битового поля без декларатора, но только двоеточие и ширина, указывает на неназванное битовое поле. В качестве особого случая это битовое поле с шириной 0 указывает на то, что никакого дополнительного битового поля должен быть упакован в блок, в котором было размещено предыдущее бит-поле, если оно есть ».

Я думаю, что он никогда не возвращает 0 в c, пустые структуры не допускаются

Вот тест, где sizeof дает 0

 #include  void func(int i) { int vla[i]; printf ("%u\n",(unsigned)sizeof vla); } int main(void) { func(0); return 0; } 

Если у вас есть это:

 struct Foo {}; struct Bar { Foo v[]; } 

g++ -ansi возвращает sizeof (Bar) == 0. Как и компилятор clang & intel.

Однако это не скомпилировано с gcc. Я выводю, что это расширение C ++.

 struct Empty { } em; struct Zero { Empty a[0]; } zr; printf("em=%d\n", sizeof(em)); printf("zr=%d\n", sizeof(zr)); 

Результат:

 em=1 zr=0 
  • Размер массивов и указателей
  • Является ли разыменование нулевого указателя действительным в операции sizeof
  • Почему sizeof (bool) не определяется как один, самим стандартом?
  • почему sizeof ('a') равен 4 в C?
  • Существуют ли платформы, где указатели на разные типы имеют разные размеры?
  • Как работает эта функция шаблона «размер массива»?
  • Можете ли вы resize массива C ++ после инициализации?
  • Размер vs Strlen
  • Почему я получаю предупреждение каждый раз, когда я использую malloc?
  • sizeof class с int, функцией, виртуальной функцией в C ++?
  • Почему sizeof (x ++) не увеличивает x?
  • Давайте будем гением компьютера.