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

时间:2013-10-02 05:08:32

标签: 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;
}

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

[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分配相同的值。为什么它缺少这个功能?编译器复杂吗?这个功能背后是否有任何理由,或者只是C的陷阱?

4 个答案:

答案 0 :(得分:11)

摘自line 1644, 6.7.8 Initialization的官方文件说:

  

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

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

答案 1 :(得分:4)

来自你的评论:

  

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

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

#define INITIAL_VALUE_FOR_A 100

int a = INITIAL_VALUE_FOR_A;
int b = INITIAL_VALUE_FOR_A;

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

其他人已经说过为什么一般的初始化者不能被允许成为任意表达式。

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

#include <stdio.h>
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;
}