9

让我举例说明,

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

4 回答 4

14

取自第 1644 行 6.7.8 Initialization的官方文档说:

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

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

于 2013-10-02T05:26:45.330 回答
5

从您的评论中:

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

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

#define INITIAL_VALUE_FOR_A 100

int a = INITIAL_VALUE_FOR_A;
int b = INITIAL_VALUE_FOR_A;

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

于 2013-10-02T05:53:41.283 回答
1

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

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

于 2013-10-02T05:11:55.190 回答
0

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

强制编译器接受代码”的方法是更改​​代码。执行文件范围、外部链接(vulgo:“全局”)变量的任意初始化的规范方法是在 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;
}
于 2013-10-02T12:04:09.557 回答