2015-06-21 87 views
4

例如:为什么空数组的大小为0但空类的大小不是0?

int main() { 
    struct {} foo; 
    int bar[0]; 
    struct { 
    int dummy[0]; 
    } baz; 
    cout << sizeof(foo) << endl; //display '1' 
    cout << sizeof(bar) << endl; //display '0' 
    cout << sizeof(baz) << endl; //display '0' 
    return 0; 
} 

请告诉我有什么原因立场背后的编译器行为

+8

C++甚至不允许零大小的数组。 C只有在大小不是一个常量表达式时才会执行。您应该在第二个和第三个案例中阅读编译器的文档以了解它的行为,因为它们是由编译器扩展而不是标准所涵盖的。 – chris

+0

相关:http://stackoverflow.com/questions/6180012/array-with-size-0 – juanchopanza

+4

**哪种语言?** C和C++是巨大的不同。特别是在这方面。你不能指望一个明智的答案“C/C++”。您可以询问C ** xor ** C++。 –

回答

10

这是一个C++的唯一问题。在C中,编译器禁止使用空的struct

在C++中,sizeof(foo) == 1的原因最终使得C++标准的“无对象应该在内存中具有与任何其他变量相同的地址”的规则可以被强制执行。您可以阅读详细信息here

编辑:关于user2864740baz出现,这也应该是非零的评论是正确的。编译器允许使用空数组,这使得看起来finessing规则没有被一致地应用到baz,就像它是到foo一样。事实上,这确实弄乱了指针算术。看到这个例子:

// C++14 code 
#include <iostream> 
using namespace std; 

int main() { 
    struct baz { 
    int dummy[1]; 
    }; 

    cout << sizeof(baz) << endl; 

    baz* arr; 
    arr = new baz[5]; 
    cout << &arr[0] << endl; 
    cout << &arr[1] << endl; 
    return 0; 
} 
// everything looks good 
4 
0x892c008 
0x892c00c 

但是,如果我们采取相同的代码和改变内部baz数组是int dummy[0];,那么我们得到如下的输出:

0 
0x8fe3008 
0x8fe3008 

危险确实;这可能会导致无限循环。建议你不要这样顽皮,即使你已经找到了逃避它的方法:)

+0

我很困惑(阅读文章后),因为'巴兹'有0大小。看起来规则也会规定它有1 /非零大小。 (除非与原代码是一个坏例子。) – user2864740

+2

@ user2864740这是因为你的代码不符合C++标准。你不能有这样的长度为零的数组。 *编辑*:看起来它是一个gcc扩展名,所以你可以不使用它或在gcc手册中阅读它应该如何工作。 – juanchopanza

+0

我不会说OP会欺骗编译器。如果行为没有在编译器文档中指定,我会感到震惊。 – chris

2

编辑:假设g++

sizeof返回对象的字节大小http://en.cppreference.com/w/cpp/language/sizeof

空的大小数组为0,因为它中没有字节。结构的大小通常不是零。如果编译器发现结构是空的,那么它将报告一个零。

就你而言,编译器可以知道结构中的字节数为零。因此,sizeof(bar)sizeof(baz)为零

看到这里也http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#The-sizeof-Operator

+2

C++不允许'sizeof(a_struct)'为零。它也不允许自动或静态存储阵列的大小为0. – juanchopanza

+1

这是一个gcc扩展https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Empty-Structures.html#Empty-结构“结构的大小为零”。回答编辑。 – bendervader

+2

这很有趣。但请注意,这不是C++。 – juanchopanza

相关问题