零长度数组与指针

编辑:显然其中一些不允许/已经改变了各种C标准。 对于我自己的假设好处,让我们假装我们使用的是gcc test.c而没有标准或警告选项。

特别是我正在研究引擎盖下的细节。 我加入了目前的理解。 我对吗?

 char **c1; //Size for a pointer is allocated on the stack. sizeof(c1) == sizeof(void*) char *c2[0]; //Nothing is allocated on the stack. sizeof(c2) == 0 

我不知道这两种情况之间是否存在其他一些差异(除了sizeof)?

 struct a { int i; char c[0]; //sizeof(a) is sizeof(int)? ac == (&i)+1? }; 

据我了解,这通常用于结构末端的可变长度数组。 但是关于

 struct b { char *c[0] //sizeof(b) is 0? where does c point? }; int j; struct b myb; //myb.c == (&j)+1 == $esp? 

此外,如果零指针的空间永远不会分配到任何地方,那么零长度数组的地址如何知道呢? 我认为常规数组的地址已知的方式相同,但我现在正努力绕过它。

我唯一一次看到实际使用的零长度数组就是你想要一个可变长度的结构。

如本例所示

  struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length; 

您不希望在上面的结构中使用指针,因为您希望内容成为结构的已分配内存的一部分。

如果在上面的结构上执行sizeof,则它不包含任何内容空间。 我不确定这是否已成为标准,它会在各种编译器上发出警告。

ISO C禁止0长度arrays。

 char **c1; 

这定义了一个对象c1 ,其类型为指向指针的指针。

 char *c2[0]; 

这是编译错误。 不允许。 不在C中,不在C ++中。

 struct a { int i; char c[0]; //sizeof(a) is sizeof(int)? ac == (&i)+1? }; 

如前所述的错误 – 数组的大小必须大于零。

  struct a { int i; char c[1]; }; 

也称为struct-hack 。 几乎所有操作系统都使用低级代码 – Linux,Windows。

C99确实为我们提供了一个无量纲arrays,更好地称为灵活arrays成员:

 struct a { int i; char c[]; /* note: no size */ }; 

您可以从GCC文档中获得一些答案。 但这侧重于将零长度数组作为结构的最后成员的主题。 它没有给出关于sizeof的直接答案。

(正如其他人所说,零长度数组不在标准C中,但它们在GNU C中。)

从C99标准(7.20.3)开始,处理分配函数:

每个这样的分配都应该产生一个指向与任何其他对象不相交的对象的指针。

[…]

如果请求的空间大小为零,则行为是实现定义的:返回空指针,或者行为就像大小是非零值一样,除了返回的指针不应用于访问对象。

换句话说,在没有初始化器的情况下在堆栈上声明b的情况下(其中bc声明为c[]而不是c[0] ),实际使用的空间b的实际大小将> 0 ,因为你无法访问b任何部分。 如果它是通过malloc分配的,它将返回0或某些无法访问的唯一值(如果使用sizeof(b) )。

数组的大小不能为零。

 ISO 9899:2011 6.7.6.2: If the expression is a constant expression, it shall have a value greater than zero. 

以上文本适用于普通数组(§1)和VLA(§5)。 这是C标准中的规范性文本。 不允许编译器以不同方式实现它。

gcc -std = c99 -pedantic给出了一个警告。