在C中初始化循环数据.这个有效的C代码是否符合任何标准?

Mat*_*att 16 c gcc recursive-datastructures circular-reference static-initialization

我想看看我是否可以初始化一个全局变量来指向自己:

#include <stdio.h>
struct foo { struct foo *a, *b; } x = { &x, &x };
int main()
{
    printf("&x = %p, x.a = %p, x.b = %p\n", &x, x.a, x.b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码编译并按预期运行gcc(所有三个指针打印相同).

我想知道:

  1. 这可靠吗?
  2. 这是标准吗?
  3. 这是便携式吗?

编辑:只是为了澄清,我质疑x其自己的初始化程序中的地址的可用性.

Jer*_*fin 8

对以上所有都是肯定的.您有几个使用相同地址初始化的指针,因此它们保持相同的地址,并且与您初始化它们的地址相同.

也许更有趣的x.a是,也保证指向自身(即,结构中的第一个元素保证在结构的最开头,因此保证转换为第一个元素类型的结构的指针)指向第一个元素.


oua*_*uah 8

这是标准C代码.

强大标准的这一段允许它(强调我的):

(C99,6.2.1p7)"结构,联合和枚举标记具有在声明标记的类型说明符中标记出现之后开始的范围.每个枚举常量具有在其定义的枚举器出现之后开始的范围.在枚举器列表中.任何其他标识符的范围都在其声明者完成之后开始. "

有关信息,请注意,为了说明6.2.1p7的最后一句,Derek M. Jones的"新C标准"一书使用了与您类似的示例:

struct T {struct T *m;} x = /* declarator complete here. */ {&x};
Run Code Online (Sandbox Code Playgroud)