sizeof可以返回0(零)
sizeof运算符有可能在C或C ++中返回0(零)吗? 如果有可能,从标准的angular度来看是否正确?
在C ++中,根据定义,空的类或结构的sizeof
至less为1。 从C ++标准中,9/3“Classes”:“类types的完整对象和成员子对象应具有非零大小”。
在C中,除了扩展名(或编译器中的缺陷)外,不允许有空的结构体。
这是语法的结果(它要求大括号内有内容)与6.7.2.1 / 7“结构和联合说明符”中的这个句子一起:“如果struct-declaration-list不包含任何命名成员,未定义“。
如果允许一个零大小的结构,那么这是一个语言扩展(或编译器中的一个缺陷)。 例如,在GCC中,扩展名在“没有成员的结构”中有记载,其中说:
GCC允许C结构没有成员:
struct empty { };
结构的大小为零。 在C ++中,空结构是语言的一部分。 G ++将空结构视为它们具有
char
types的单个成员。
sizeof
从不在C和C ++中返回0
。 每当你看到sizeof
评估为0
这是一个特定编译器的错误/毛刺/扩展,与语言无关。
C中的每个对象都必须有唯一的地址。 换个angular度来说,一个地址必须只包含一个给定types的对象(为了使指针取消引用起作用)。 这就是说,考虑一个“空”的结构:
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
运算符的结果是对象中的字节数,包括使对象平铺为数组所需的任何填充
由于必须将填充字节添加到“空”对象以使其在数组中工作,因此对于任何有效input, sizeof()
必须返回至less1的值。
编辑: C规范的A8.3节调用一个没有成员列表的结构不完整的types ,以及特定状态的sizeof
的定义(重点添加):
运算符(sizeof) 可能不适用于函数types或不完整types 的操作数 , 也可能不适用于位域。
这意味着在一个空的结构体上使用sizeof
与在未定义的数据types上使用sizeof
一样无效。 如果您的编译器允许使用空结构,请注意,根据C规范,不允许在其上使用sizeof
。 如果您的编译器允许您执行此操作,请理解这是非标准行为,不适用于所有编译器; 不要依赖这种行为。
编辑:另请参阅Bjarne Stroustrup常见问题中的这个条目 。
空白的结构,正如isbadawi所 提到的那样 。 另外gcc允许0大小的数组 :
int a[0]; sizeof(a);
编辑:看到MSDN链接后,我试图在VS2005中的空结构和sizeof返回1.我不知道如果这是一个VS错误,或者如果规范是这样的东西灵活
在我看来,sizeof对于0的结构返回0(本质上是c)更好。 但是程序员在获取空结构的大小时必须小心。
但可能会导致问题。 当这样的结构数组被定义时,那么
&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的位域表示不再有位域将被装入前一个位域(如果有的话)的单元中。
我认为它在c中从不返回0,不允许有空结构
这是一个testing,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; }
如果你有这个:
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