创建大小为零的灵活数组成员是否合法?

时间:2011-02-18 04:48:05

标签: c struct c99 flexible-array-member

C99标准允许创建灵活的阵列成员,例如

typedef struct pstring {
  size_t length;
  char   string[];
} pstring;

然后使用类似pstring* s = malloc(sizeof(pstring) + len)的内容对其进行初始化。允许len为零吗?它似乎是一致的,并且不时地节省空间(当然可能不是pstring示例)。另一方面,我不知道下面的代码会做什么:

pstring* s = malloc(sizeof(pstring));
s->string;

这看起来似乎可能适用于一个编译器而不是另一个编译器,或者在一个操作系统而不是另一个操作系统上,或者在某一天而不是另一个,所以我真正想知道的是标准说到这一点。示例代码中的malloc是未定义的行为,还是仅对无效的s->string的访问,还是完全不同的其他内容?

2 个答案:

答案 0 :(得分:6)

您所做的是有效的,但访问s-> string [0]或将s->字符串输入到访问数据的任何函数都无效。

C99标准实际上说(§6.7.2.1):

  

struct s { int n; double d[]; };

     

...

     

struct s t1 = { 0 }; // valid

     

...

     

t1.d[0]的分配可能是未定义的行为,但有可能

     

sizeof (struct s) >= offsetof(struct s, d) + sizeof (double)

     

在这种情况下,作业是合法的。然而,它不能严格符合要求   代码。

答案 1 :(得分:1)

有一段时间,Microsoft C允许以下内容:

struct pstring {
  size_t length;
  char string[0];
};

我使用这样的东西来构建文本编辑器。然而,这是很久以前的事了,我知道当时它不合标准。我甚至不是100%确定微软仍然支持它。

底线是它取决于您的编译器和当前的编译设置。