"Initializer element is not constant" 将对象定义为函数的静态成员时
"Initializer element is not constant" when defining an object as a static member of a function
以下代码编译无异议:
struct s {
const int a;
};
static const struct s *s = &(const struct s) {
.a = 5
};
int main(void) {
(void) s;
return 0;
}
但是,如果我们将 s
的定义移动到 main
的主体,即:
struct s {
const int a;
};
int main(void) {
static const struct s *s = &(const struct s) {
.a = 5
};
(void) s;
return 0;
}
我们得到错误:
error: initializer element is not constant
static const struct s* s = &(const struct s) {
^
因为在这两种情况下,我们都处理静态(即编译时)初始化,为什么第二个用例是非法的?
有什么办法让它在函数的上下文中合法吗?
(我用 GCC 7.3.0 和 clang 6.0.0 检查过,他们都报错)
根据 C 2018 6.6(“常量表达式”)7:
More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following: … an address constant, or…
每 6.6 9:
An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator…
那么,在 6.5.2.5(“复合文字”)5 中,我们有:
… If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.
因此,在第一种情况下,复合文字是一个具有静态存储持续时间的对象,指向它的指针是一个地址常量。第二种情况,复合字面量是一个自动存储持续时间的对象,指向它的指针不是地址常量。
以下代码编译无异议:
struct s {
const int a;
};
static const struct s *s = &(const struct s) {
.a = 5
};
int main(void) {
(void) s;
return 0;
}
但是,如果我们将 s
的定义移动到 main
的主体,即:
struct s {
const int a;
};
int main(void) {
static const struct s *s = &(const struct s) {
.a = 5
};
(void) s;
return 0;
}
我们得到错误:
error: initializer element is not constant
static const struct s* s = &(const struct s) {
^
因为在这两种情况下,我们都处理静态(即编译时)初始化,为什么第二个用例是非法的? 有什么办法让它在函数的上下文中合法吗?
(我用 GCC 7.3.0 和 clang 6.0.0 检查过,他们都报错)
根据 C 2018 6.6(“常量表达式”)7:
More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following: … an address constant, or…
每 6.6 9:
An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator…
那么,在 6.5.2.5(“复合文字”)5 中,我们有:
… If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.
因此,在第一种情况下,复合文字是一个具有静态存储持续时间的对象,指向它的指针是一个地址常量。第二种情况,复合字面量是一个自动存储持续时间的对象,指向它的指针不是地址常量。