【问题标题】:Definition of global variables using a non constant initializer使用非常量初始化器定义全局变量
【发布时间】:2026-01-10 15:45:01
【问题描述】:
#include <stdio.h>

int i=10;
int j=i;
int main()
{
    printf("%d",j);
}

我收到一条错误消息,指出初始化元素不是常量?这背后的原因是什么?

【问题讨论】:

  • i 是一个变量,而不是一个常数。并且 C 不允许全局或静态变量的非常量初始值设定项。 C 在这方面与 C++ 不同。
  • @ATaylor 不。 const int 没有解决它。
  • @user963472:在 C 中(与 C++ 不同)const 声明不会产生常量表达式。
  • @Vignesh_dino: const 并不意味着恒定;这意味着只读。 (并且const 在 C++ 中并不总是暗示 constant;请考虑 const int r = rand();。)

标签: c global-variables


【解决方案1】:

这背后的原因是什么?

C(与 C++ 不同)不允许使用非常量值初始化全局值。

C99 标准:第 6.7.8 节:

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

【讨论】:

  • 我在网上看到有静态存储的变量是在加载时分配的。这和我上面的问题有什么关系吗?
  • @user963472:我不明白你的问题。能详细点吗?
【解决方案2】:

您可以尝试使用:

int i=10;
int j=0;

int main()
{
   j=i;//This should be the first statement in the main() and you achieve the same functionality as ur code
   return 0;
}

唯一真正的 C 方法是在运行时初始化它。虽然在 C++ 中你的代码可以正常工作,没有任何编译错误。

C 标准明确禁止使用非常量值初始化全局对象。 C99 标准的Section 6.7.8 说:

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

static storage duration 的对象定义在第 6.2.4 节:

标识符用外部或内部声明的对象 链接,或使用存储类说明符 static 具有静态存储 期间。它的生命周期是程序的整个执行过程及其 存储的值仅在程序启动之前初始化一次。

【讨论】:

    【解决方案3】:

    此要求背后的想法是在编译时初始化所有静态存储持续时间对象。编译器以预初始化的形式准备所有静态数据,以便在运行时不需要额外的初始化代码。 IE。当编译的程序被加载时,所有这些变量都以已经初始化的状态开始它们的生命。

    在 C 语言的第一个标准化版本 (C89/90) 中,此要求也适用于聚合初始化器,即使它们与局部变量一起使用也是如此。

    void foo(void)
    {
      int a = 5;
      struct S { int x, y; } s = { a, a }; /* ERROR: initializer not constant */
    }
    

    显然,限制的原因是聚合初始化器应该在预初始化的数据段中预先构建,就像全局变量一样。

    【讨论】:

      【解决方案4】:

      使用这个:-

      int i=10,j=1;
      int main()
      {
        printf("%d",j);
      }
      

      虽然这是一个小改动,但它会起作用

      【讨论】: