为什么编译器限制全局变量始终用常量值初始化?

dex*_*ous 8 c

让我举例说明一下,

int a = 100;
int b = a;

int main(int argc, char **argv, char ** env)
{
  printf("The value of b=%d\r\n",b);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,我按预期得到了编译错误.

[joshis1@localhost global_var]$ gcc global_var.c -o global_var.out
global_var.c:4:1: error: initializer element is not constant
 int b = a;
 ^
Run Code Online (Sandbox Code Playgroud)

我想在这里学到的是为什么我会得到错误?为什么编译器限制此操作.我知道初始化的全局变量存储在数据段中.编译器可以首先解析a的值,然后可以为b分配相同的值.为什么它缺少这个功能?编译器复杂吗?这个功能背后是否有任何理由或只是C的陷阱?

Ken*_*Y-N 11

官方文档取自1644行,6.7.8初始化,说:

具有静态存储持续时间的对象的初始化程序中的所有表达式应为常量表达式或字符串文字.

为什么规则存在是一个更难的问题 - 也许正如你所说的那样,编译器很难做到.在C++中,这样的表达式是有效的,但是全局初始化器可以调用构造函数等,而对于C,为了保持紧凑,在编译阶段对全局变量进行求值.int b = a;在编译时是可评估的,但是怎么样int b = a + c;int b = pow(a, 2);?你会在哪里停下来?C决定不允许你开始是最好的解决方案.

  • 编译器不仅仅是"难".它触及了停止问题.如果静态初始化不是常量,那么在编译时评估它们将需要解释可能不会终止的已解析代码.另一方面,如果静态初始化不是常量,但它们是在运行时确定的,那么您将需要一个非常复杂的机制来检测和排序所有静态初始化.C++接近这一点,但它远非直截了当.基本上不保证初始化块之间的顺序. (5认同)

Jim*_*des 5

从你的评论:

...我怎样才能强制编译器使这项工作?

好吧,您不能让编译器接受您拥有的内容,但是您可以通过定义要分配给两个变量的值来实现您的目标。

#define INITIAL_VALUE_FOR_A 100

int a = INITIAL_VALUE_FOR_A;
int b = INITIAL_VALUE_FOR_A;
Run Code Online (Sandbox Code Playgroud)

现在如果需要更改初始值,只需要在一处更改即可;

  • @SHREYASJOSHI 如果您对“您不能;语言禁止这样做”不满意,那么您使用的是错误的语言。想想等式的哪一部分在你的控制之下。 (4认同)