提问人:bolov 提问时间:11/17/2017 最后编辑:bolov 更新时间:11/22/2017 访问量:6814
这个结构怎么会有 sizeof == 0?
How can this structure have sizeof == 0?
问:
有一个旧帖子要求一个可以返回的构造.一些来自高声誉用户的高分回答说,根据标准,任何类型或变量都不能有 sizeof 0。我100%同意这一点。sizeof
0
但是,有这个新答案提出了这个解决方案:
struct ZeroMemory {
int *a[0];
};
我正要投反对票并发表评论,但在这里度过的时间教会了我检查我 100% 确定的事情。所以。。。令我惊讶的是,两者都显示了相同的结果:.更重要的是,变量的大小是:gcc
clang
sizeof(ZeroMemory) == 0
0
ZeroMemory z{};
static_assert(sizeof(z) == 0); // Awkward...
呜
这怎么可能?
答:
正如 Jarod42 所指出的,零大小数组不是标准的 C++,而是 GCC 和 Clang 扩展。
添加会产生以下警告:-pedantic
5 : <source>:5:12: warning: zero size arrays are an extension [-Wzero-length-array] int *a[0]; ^
我总是忘记(而不是)不会禁用所有扩展。std=c++XX
std=gnu++XX
这仍然不能解释这种行为。但至少我们知道这不是标准的......sizeof
评论
sizeof(int*)
sizeof
ZeroMemory* z = (ZeroMemory*)malloc(sizeof(ZeroMemory) + 2 * sizeof(int*)); z.a[1] = new int{1}; /* or whatever, just use indices into a to access dynamic memory after the previous members (in this case: none) */
在 C++ 中,零大小数组是非法的。
ISO/IEC 14882:2003 8.3.4/1:
[..]如果常量表达式 (5.19) 存在,则它应该是一个整数常量表达式,其值应大于零。常量表达式指定数组的边界(元素数)。如果常量表达式的值为 ,则数组的元素编号为 ,标识符的类型为 “derived-declarator-type-list array of T”。[..]
N
N
0
N-1
D
N
G++ 要求该标志对零大小的数组发出警告。-pedantic
零长度数组是 GCC 和 Clang 的扩展。应用于长度为零的数组的计算结果为零。sizeof
C++ 类(空)不能有 size ,但请注意该类不为空。它有一个具有大小的命名成员,应用将返回零。0
ZeroMemory
0
sizeof
评论
0
0
0
在 C 语言标准化之前,许多编译器在处理零大小类型时不会遇到困难,只要代码从未尝试从另一个指向零大小类型的指针中减去另一个指针。这种类型很有用,支持它们比禁止它们更容易、更便宜。然而,其他编译器决定禁止这种类型,一些静态断言代码可能依赖于这样一个事实,即如果代码试图创建一个零大小的数组,它们会发出嘶嘶声。该标准的作者面临着一个选择:
允许编译器以静默方式接受零大小的数组声明,甚至 如果此类声明的目的是触发 诊断和中止编译,并要求所有编译器都接受 这样的声明(尽管不一定是默默的)产生零 调整大小的对象。
允许编译器以静默方式接受零大小的数组声明,甚至 如果此类声明的目的是触发 诊断和中止编译,并允许编译器遇到这样的 声明要么中止编译,要么在闲暇时继续编译。
如果代码声明 零大小的数组,但随后允许实现中止 编译或继续它(使用他们认为合适的任何语义) 他们的闲暇。
该标准的作者选择了#3。因此,零大小数组声明被标准“扩展”视为,尽管在标准禁止它们之前,这种结构被广泛支持。
C++ 标准允许空对象的存在,但为了允许空对象的地址可用作令牌,它要求它们的最小大小为 1。因此,对于没有成员的对象,其大小为 0 将违反标准。但是,如果对象包含零大小的成员,则 C++ 标准对如何处理它没有要求,除了包含此类声明的程序必须触发诊断这一事实之外。由于使用此类声明的大多数代码都期望生成的对象的大小为零,因此对于接收此类代码的编译器来说,最有用的行为是以这种方式处理它们。
评论
struct polygon { int count; POINT sides[0];}; struct { struct polygon poly; POINT pts[3]; } myTriangle = { {3}, {{1,1},{2,2},{2,1} };
评论