我可以声明一个 C 指针并对其自己的地址进行初始化吗?
void* p = &p;
我特别关心这是否严格符合 C23 标准(目前的草案)。
我认为这个问题相当于以下内容是否有效,这更接近我的实际用例:
typedef struct st {
void* p;
} st;
st x = { .p = &x };
应该没问题。我想不出标准的任何部分会使其无效,并且 C23 也没有带来任何改变这一点的新内容。
该标准最相关的部分是关于用作初始值设定项的地址常量的 6.6(来自 C23 草案 N3096):
C23 中的新内容如下,主要与地址常量是一个空指针,指向指定静态存储对象的左值的指针 持续时间,或指向函数指示符的指针;它应该使用一元
&
显式创建 运算符或整数常量转换为指针类型,或隐式使用数组或的表达式 函数类型。数组下标
[]
和成员访问->
运算符、地址&
和间接*
一元运算符以及指针强制转换可用于创建地址常量,但对象的值不得使用这些运算符进行访问。
constexpr
情况和复合文字相关:
从超越 C 标准的实际角度来看,我们声明的任何变量在初始化之前都应该已经有一个内存位置,否则程序如何知道在哪里存储该初始化程序? (使用结构或联合常量分别是具有结构或联合类型的命名常量或复合文字常量。
实现可以接受其他形式的常量表达式;但是,它们不是整数 常数表达式。从结构或联合常量开始,成员访问
.
运算符可用于形成如上所述的命名常量或复合文字常量。如果成员访问运算符.
访问联合常量的成员,则访问的成员应与联合常量的初始值设定项初始化的成员相同。
&
运算符也意味着它不能存储在寄存器中。)C 标准在涉及变量在内存中的位置/如何存储时故意含糊不清,因此它不会涵盖诸如链接器地址之类的内容,堆栈偏移量等。