这个结构如何具有sizeof == 0? [英] How can this structure have sizeof == 0?
问题描述
有一个老帖子要求一个sizeof
将返回0
的构造.来自高声誉用户的一些高分答案说,按标准,类型或变量的大小不能为0.我同意100%.
There is an old post asking for a construct for which sizeof
would return 0
. There are some high score answers from high reputation users saying that by the standard no type or variable can have sizeof 0. And I agree 100% with that.
但是,有这个新答案提供了以下解决方案:
However there is this new answer which presents this solution:
struct ZeroMemory {
int *a[0];
};
我正要投票反对它,但在这里花费的时间教会了我什至对我100%确信的事情进行检查.所以...令我惊讶的是gcc
和clang
都显示相同的结果:sizeof(ZeroMemory) == 0
.更重要的是,变量的大小为0
:
I was just about to down-vote and comment on it, but time spent here taught me to check even the things that I am 100% sure on. So... to my surprise both gcc
and clang
show the same results: sizeof(ZeroMemory) == 0
. Even more, sizeof a variable is 0
:
ZeroMemory z{};
static_assert(sizeof(z) == 0); // Awkward...
哇......
这怎么可能?
推荐答案
在将C标准化之前,只要代码从未尝试将一个指针指向零尺寸类型,那么许多编译器在处理零尺寸类型时就不会遇到困难.从另一个.这样的类型是有用的,并且与禁止它们相比,对它们的支持更容易,更便宜.但是,其他编译器决定禁止这种类型,并且某些静态断言代码可能依赖于这样的事实,即如果代码尝试创建零大小的数组,它们会发出嘎嘎声.该标准的作者面临一个选择:
Before C was standardized, many compilers would have had no difficulty handling zero-size types as long as code never tried to subtract one pointer to a zero-size type from another. Such types were useful, and supporting them was easier and cheaper than forbidding them. Other compilers decided to forbid such types, however, and some static-assertion code may have relied upon the fact that they would squawk if code tried to create a zero-sized array. The authors of the Standard were faced with a choice:
-
允许编译器静默接受零大小的数组声明,甚至 如果此类声明的目的是触发 诊断和中止编译,并要求所有编译器都接受 这样的声明(尽管不一定默默地产生)为零, 大小的对象.
Allow compilers to silently accept zero-sized array declarations, even in cases where the purpose of such declarations would be to trigger a diagnostic and abort compilation, and require that all compilers accept such declarations (though not necessarily silently) as producing zero- sized objects.
允许编译器静默接受零大小的数组声明,甚至 如果此类声明的目的是触发 诊断和中止编译,并允许编译器遇到这种情况 声明以中止编译或在闲暇时继续进行编译.
Allow compilers to silently accept zero-sized array declarations, even in cases where the purpose of such declarations would be to trigger a diagnostic and abort compilation, and allow compilers encountering such declarations to either abort compilation or continue it at their leisure.
要求实现在代码声明以下内容时发出诊断信息: 零大小的数组,但随后允许实现中止 编译或继续(使用他们认为合适的语义) 他们的闲暇.
Require that implementations issue a diagnostic if code declares a zero-sized array, but then allow implementations to either abort compilation or continue it (with whatever semantics they see fit) at their leisure.
该标准的作者选择了#3.因此,即使标准禁止这种构造得到了广泛的支持,标准的扩展名"仍将零大小的数组声明视为该构造.
The authors of the Standard opted for #3. Consequently, zero-sized array declarations are regarded by the Standard "extension", even though such constructs were widely supported before the Standard forbade them.
C ++标准允许存在空对象,但是为了允许将空对象的地址用作令牌,它要求它们的最小大小为1.对于没有成员的对象,如果大小为0,则将违反标准.但是,如果对象包含零大小的成员,则C ++标准对包含如何声明该对象的程序必须触发诊断的事实不加任何要求.由于大多数使用此类声明的代码都希望生成的对象的大小为零,因此对于接收此类代码的编译器而言,最有用的行为就是以这种方式对其进行处理.
The C++ Standard allows for the existence of empty objects, but in an effort to allow the addresses of empty objects to be usable as tokens it mandates that they have a minimum size of 1. For an object that has no members to have a size of 0 would thus violate the Standard. If an object contains zero-sized members, however, the C++ Standard imposes no requirements about how it is processed beyond the fact that a program containing such a declaration must trigger a diagnostic. Since most code that uses such declarations expects the resulting objects to have a size of zero, the most useful behavior for compilers receiving such code is to treat them that way.
这篇关于这个结构如何具有sizeof == 0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!