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

Ant*_*sky 1 c struct c99 flexible-array-member

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

typedef struct pstring {
  size_t length;
  char   string[];
} pstring;
Run Code Online (Sandbox Code Playgroud)

然后用类似的东西初始化pstring* s = malloc(sizeof(pstring) + len).len为零是允许的吗?它似乎是一致的,并且不时地节省空间(pstring当然可能不是这个例子).另一方面,我不知道下面的代码会做什么:

pstring* s = malloc(sizeof(pstring));
s->string;
Run Code Online (Sandbox Code Playgroud)

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

Zul*_*lan 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)

在这种情况下,转让是合法的.然而,它不能出现在严格符合规范的代码中.