我有这个非常简单的程序:
int main(void)
{
static constexpr const char *const str = "hello";
}
无法编译并出现此错误:
$ gcc -std=c2x str.c
str.c: In function 'main':
str.c:6:46: error: 'constexpr' pointer initializer is not null
6 | static constexpr const char *const str = "hello";
| ^~~~~~~
$ gcc -v
...
gcc version 13.1.0 (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders)
为什么
nullptr
是唯一允许的指针类型是constexpr
?
C23 标准明确规定,声明为
constexpr
的指针必须进行空初始化,根据第 6.7.1p5 节:
使用存储类说明符
声明的对象或任何 它的成员,即使是递归的,也不应该有原子类型,或者 可变修改类型,或constexpr
或volatile
的类型 合格的。该声明应是一个定义并应具有 初始化器141)。任何常量表达式或任何的值 初始化程序的字符串文字中的字符应完全相同 可在相应的目标类型中表示;价值没有变化 应适用142)。 如果一个对象或子对象声明为 存储类说明符restrict
具有指针、整数或算术 类型,它的隐式或显式初始化值应为 空指针常量143),整数常量表达式,或 分别是算术常量表达式。constexpr
- 对应的命名常量或复合文字常量 使用存储类说明符
和指针声明的对象 type 是一个值为 null 的常量表达式,因此是一个 null 指针和地址常量。然而,即使它有类型constexpr
它 不是空指针常量。void *
这似乎是标准中的一个缺陷,因为它不允许使用地址常量(例如字符串文字的起始地址)进行初始化。