C23标准下能否将指针或结构体成员初始化为自身地址?
关于C23标准下自引用指针初始化的合法性
1. void* p = &p; 的合法性
在C23标准草案中,这种写法是合法的。
根据C23的初始化规则:当初始化一个对象时,初始化表达式中可以引用该对象的地址——因为地址是对象的固有属性,在对象的存储空间被分配后就已确定,无需等待初始化完成。此前的C标准(如C17)虽未明确提及,但编译器通常也会兼容这种写法,而C23则正式将这类自引用地址的初始化纳入合规范畴。
需要明确的是,这里我们只是用变量p自身的存储地址来初始化它的指针值,并没有访问未初始化的对象内容,完全不存在“未定义对象引用”的问题,逻辑自洽。
2. 结构体初始化写法的等价性
你给出的结构体代码:
typedef struct st { void* p; } st; st x = { .p = &x };
和第一个例子完全等价,且同样符合C23标准草案。
这本质上属于对象的自引用初始化:结构体变量x的存储地址在初始化阶段已确定,用&x初始化它的成员p,和直接初始化指针变量指向自身地址的逻辑完全一致。这类写法在实际场景中常用于实现环状结构、自引用链表节点等,C23明确允许此类操作。
补充说明
要区分两种自引用场景:用对象的地址初始化自身指针是合法的,但如果用对象的未初始化值来初始化自己(比如int a = a;),则依然属于未定义行为——地址的确定不依赖对象的值,而值的引用则会访问未初始化的内存。
内容的提问来源于stack exchange,提问作者Kyle
相关产品推荐
相关产品推荐

