Muh*_*aby 0 c c++ initialization language-lawyer storage-duration
为什么下面的代码编译为 C++ 时没有任何抱怨,但 C 编译器却抱怨初始化器不是编译时常量?
int x = 2;
int y = 1;
int a[2] = {x, y};
#include <stdio.h>
int main()
{
printf("Hello world\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
来自 C11 标准(6.7.9 初始化)
\n\n\n4 具有静态或线程存储持续时间的对象的初始值设定项中的所有表达式都应为常量表达式或字符串文字。
\n
在 C 中这些声明
\nint x = 2;\nint y = 1;\nRun Code Online (Sandbox Code Playgroud)\n不提供常量表达式。就算你会写
\nconst int x = 2;\nconst int y = 1;\nRun Code Online (Sandbox Code Playgroud)\n然后,它们再次不提供允许用作具有静态存储持续时间的对象的初始值设定项的编译时常量表达式。
\n来自 C11 标准(6.6 常量表达式)
\n\n\n7 初始值设定项中的常量表达式允许有更多的自由度。\n这样的常量表达式应为以下之一,或计算为以下之一:\n
\n\xe2\x80\x94 算术常量表达式,
\n\xe2\x80\x94 空指针常量,
\n\xe2\x80\x94 地址常量,或
\n\xe2\x80\x94 完整对象类型的地址常量加上或减去整数常量表达式。
\n
和
\n\n\n8算术常量表达式应具有算术类型,并且只能具有整型常量、浮点常量、枚举常量、字符常量和sizeof表达式的操作数。算术常量表达式中的转换运算符只能将算术类型转换为算术类型,除非作为结果为整型常量的 sizeof 运算符的操作数的一部分。
\n
如果您的编译器支持 C23 标准,那么您可以编写
\nconstexpr int x = 2;\nconstexpr int y = 1;\n\nint a[2] = { x, y };\nRun Code Online (Sandbox Code Playgroud)\n在 C23 中,标识符x和y被称为命名常量,并且命名常量可以用作具有静态存储持续时间的对象的初始值设定项。
在 C++ 中,具有静态存储持续时间的对象的初始化
\nint x = 2;\nint y = 1;\n\nint a[2] = { x, y };\nRun Code Online (Sandbox Code Playgroud)\n称为动态初始化并在运行时发生。
\n