C语言中0长度数组的意义是什么?

8
#include <stdio.h>
int main()
{
    int a[0],b[4][0];
    printf("%d %d ",sizeof(a),sizeof(b));
}
//output
0 0

a[0]的意义是什么?为什么允许大小为0的2D数组?

3个回答

9

无论是C还是C++都不允许长度为零的数组,因此您的程序是非法的。

例如,C++11,8.3.4/1:“[数组大小]必须大于零”。

(从一个合理性的角度来看:长度为零的数组会与每个对象具有唯一地址的要求产生棘手和混乱的关系。)

正如@sidyll指出的那样,长度为零的数组在GCC中作为扩展可用。


在gcc编译器的Ubuntu 10.04上,它没有报错。 - Utkarsh Srivastav
4
有很多种方法可以编写不规范的C和C ++程序,并且您将不会收到任何诊断信息。对此,我的GCC会显示“警告:ISO C ++禁止零大小数组”。您应始终启用所有警告。 - Kerrek SB
1
你为什么要用C++编译器编译一个C程序,然后发布一个C++标准的摘录呢? - sidyll
@sidyll:GCC 对于 C 的所有三个版本都会显示“警告:ISO C 禁止零大小数组”。 - Kerrek SB
1
-Wall -Wextra 后面,我建议使用一些 -Wno-... 选项。gcc 包含一些荒谬的东西,会在正确的程序上出现虚假触发,并且甚至会在某些情况下强制你避开最佳实践,如果你想消除警告(例如,你不能对不透明类型使用通用的零初始化器 {0})。 - R.. GitHub STOP HELPING ICE
显示剩余3条评论

3

您可以在GCC手册中找到答案。

如果您正在使用c99

  • 灵活数组成员写作contents[]而没有0。
  • 灵活数组成员具有不完整的类型,因此无法应用sizeof运算符。由于零长度数组的原始实现的怪癖,sizeof评估为零。
  • 灵活数组成员只能出现在除非非空,否则最后一个成员的结构中。
  • 包含灵活数组成员的结构或包含这样一个结构的联合体(可能是递归的)不能成为结构的成员或数组的元素。(但是,作为扩展,这些用途被GCC允许)。

当然,它们如何有用:

Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure which is really a header for a variable-length object:

struct line {
   int length;
   char contents[0];
 };

struct line *thisline = (struct line *)
   malloc (sizeof (struct line) + this_length);
 thisline->length = this_length;

1
在C11和C99中,sizeof不总是编译时运算符(这只存在于C89中)。 - Kerrek SB

1

在您的示例中,它并没有太多用处,但是零大小数组经常用于结构中,其中最后一个元素具有动态大小:

struct {
     int    some_fixed_data [N_FIXED];
     float  more_fixed_size_data [F_FIXED];
     int    n_variable_elements;
     long   variable_elements [0];  // allocated based on item above
} s;

int curlen = sizeof s + sizeof long * s.n_variable_elements;

使用零长度数组的好处是:

1)即使某些人的答案不同,variable_elements 仍然有一个地址
2)它也具有数组语义
3)计算数组的动态大小变得更加简单

不幸的是,一些编译器(如MSC)会对这种结构产生错误,并强制进行较小、讨好但技术上不正确的改写:

struct {
     int    some_fixed_data [N_FIXED];
     float  more_fixed_size_data [F_FIXED];
     int    n_variable_elements;
     long   variable_elements [1];  // allocated based on item above
} s;

int curlen = sizeof s + sizeof long + (s.n_variable_elements - 1);

将零大小的数组视为占位符。除非你被迫使用 C 语言(在许多嵌入式环境中是这样),否则几乎没有必要这样做了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接