Может sizeof возвращаться 0 (нуль)

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

50
задан TheJuice 13 April 2010 в 07:47
поделиться

7 ответов

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

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

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

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

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

  struct empty {
 }; 
 

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

40
ответ дан 7 November 2019 в 11:01
поделиться

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

int a[0];
sizeof(a);

РЕДАКТИРОВАТЬ: Увидев ссылку MSDN, я попробовал пустую структуру в VS2005, и sizeof вернул 1. Я не уверен, что это ошибка VS или спецификация в некоторой степени гибка в отношении подобных вещей

5
ответ дан 7 November 2019 в 11:01
поделиться

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

0
ответ дан 7 November 2019 в 11:01
поделиться

Каждый объект в 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 Бьярна Страуструпа.

9
ответ дан 7 November 2019 в 11:01
поделиться

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

20
ответ дан 7 November 2019 в 11:01
поделиться

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

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

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

, что заставляет их проигрывать их личности.

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

2
ответ дан 7 November 2019 в 11:01
поделиться

Вот тест, где 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;
}
0
ответ дан 7 November 2019 в 11:01
поделиться