sizeof可以返回0(零)

The*_*ice 50 c c++ sizeof

sizeof运算符是否有可能在C或C++中返回0(零)?如果可能的话,从标准的角度来看是否正确?

Mic*_*urr 40

在C++中,sizeof根据定义,空类或结构至少有1个.从C++标准来看,9/3"类":"类类型的完整对象和成员子对象应具有非零大小."

在C中,除了扩展名(或编译器中的缺陷)之外,不允许使用空结构.

这是语法的结果(要求括号内有东西)以及6.7.2.1/7"结构和联合说明符"中的这句话:"如果struct-declaration-list不包含命名成员,则行为未定义".

如果允许零大小的结构,则它是语言扩展(或编译器中的缺陷).例如,在GCC中,扩展名记录在"没有成员的结构"中,其中说:

GCC允许C结构没有成员:

 struct empty {
 };
Run Code Online (Sandbox Code Playgroud)

结构的大小为零.在C++中,空结构是语言的一部分.G ++将空结构视为具有单个类型成员char.

  • @Michael Burr:实际上,语法本身已经禁止空结构.C中的空结构立即是语法错误,而不是UB.关于"没有命名成员 - UB"的评论是关闭一个不同的漏洞.您可以声明`struct {int:1}`(即一个未命名的位域)来正式满足语法要求.要取缔这样的事情那里有额外的评论. (5认同)
  • @TheJuice:语法要求在结构定义中有一些东西,但我认为你可能只用一个分号就可以逃脱(语法方面)(我不确定那个 - 读BNF不是我强大的西装之一).但是,如果你在结构定义中没有任何带有名字的东西,那么你就处于未定义的行为领域(它真的没有给你买任何东西 - 你不能指望它做任何合理的事情). (2认同)
  • @Andrey:我明白了,C99§6.7.2.1/ 4"位字段的类型应该是_Bool,signed int,unsigned int或其他一些实现定义类型的限定或非限定版本." 另外,我刚刚测试了`int:1`方式,而GCC和G ++确实使它的大小为1.抱歉. (2认同)
  • gcc 确实为空结构体的 sizeof 返回 0;int main(){ printf("%i",sizeof(struct {})); } (2认同)

AnT*_*AnT 20

sizeof永远不会0在C和C++中返回.每次你看到sizeof评估0它是一个与语言无关的特定编译器的错误/故障/扩展.

  • @MK:语言标准是参考.那里没有一个地方.这一切都源于这样的事实:根据定义,任何对象类型在C或C++中都具有非零大小.你不能将`sizeof`应用于不完整类型的事实也起着重要作用.等等. (7认同)
  • 参考或它没有发生. (2认同)

bta*_*bta 9

C中的每个对象都必须具有唯一的地址.换句话说,一个地址必须只包含一个给定类型的对象(为了使指针解除引用起作用).话虽如此,考虑一个'空'结构:

struct emptyStruct {};
Run Code Online (Sandbox Code Playgroud)

更具体地说,它们的数组:

struct emptyStruct array[10];
struct emptyStruct* ptr = &array[0];
Run Code Online (Sandbox Code Playgroud)

如果对象确实是空的(即,如果sizeof(struct emptyStruct) == 0),那么ptr++ ==> (void*)ptr + sizeof(struct emptyStruct) ==> ptr,这是没有意义的.*ptr然后会引用哪个对象,ptr[0]或者ptr[1]

即使结构没有内容,编译器也应将其视为长度为一个字节,以保持"一个地址,一个对象"的原则.

C语言规范(A7.4.8节)将此要求称为

当应用于结构或联合时,结果(sizeof运算符)是对象中的字节数,包括使对象平铺数组所需的任何填充

由于必须将填充字节添加到"空"对象以使其在数组中工作,sizeof()因此必须为任何有效输入返回至少为1的值.

编辑: C规范的A8.3节调用一个没有成员列表的结构,一个不完整的类型,以及sizeof特定状态的定义(强调添加):

运算符(sizeof)可能不适用于函数类型的操作数,或不完整类型的操作数,也不适用于位字段.

这意味着sizeof在空结构上使用与在未定义的数据类型上使用它同样无效.如果您的编译器允许使用空结构,请注意sizeof不允许根据C规范使用它们.如果您的编译器允许您仍然执行此操作,请了解这是非标准行为,不适用于所有编译器; 不要依赖这种行为.

编辑:请参阅Bjarne Stroustrup常见问题解答中的此条目.


Mic*_*zek 5

Isbadawi 提到的空结构.gcc也允许0大小的数组:

int a[0];
sizeof(a);
Run Code Online (Sandbox Code Playgroud)

编辑:在看到MSDN链接后,我在VS2005中尝试了空结构,并且sizeof确实返回1.我不确定这是否是一个VS错误,或者规范是否在某种程度上是灵活的

  • 仅仅因为GCC允许它不能使它成为合法的C/C++. (3认同)