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

让我举例说明一下,

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; } 

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

 [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; ^ 

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

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

具有静态存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字。

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

从你的评论:

…我如何强制编译器使其工作?

那么你不能让编译器接受你拥有的东西,但你可以通过定义你想要分配给两个变量的值来实现你的目标。

 #define INITIAL_VALUE_FOR_A 100 int a = INITIAL_VALUE_FOR_A; int b = INITIAL_VALUE_FOR_A; 

现在,如果您需要更改初始值,您只需要在一个地方更改它;

C可移植到非常简单的小型机器上。 在函数中评估非常量的表达式需要运行时代码。 在嵌入式编程中,您可能不需要任何未明确编程的函数(或代码)。

如果配置了不同的选项,您的编译器可能会将初始化程序评估为语言扩展。 如果失败了,你可以尝试C ++(甚至只是类似C的子集)或其他可以做更多你喜欢的事情的语言:v)。

其他人已经说明为什么不能允许初始化器是任意表达式。

强制编译器接受代码 ”的方法是更改代码 。 执行文件范围,外部链接(vulgo:“global”)变量的任意初始化的规范方法是在main()的开头调用初始化函数,该函数执行所需序列中的所有初始化:

 #include  int a; int b; void init(void) { a = 100; b = a; } int main(int argc, char **argv) { init(); printf("The value of b=%d\n", b); return 0; }