【问题标题】:When does initialisation of global variables happen?全局变量的初始化何时发生?
【发布时间】:2012-01-03 18:56:42
【问题描述】:

我知道当一个程序运行时,main()函数首先被执行。但是在 main() 之外声明的全局变量的初始化什么时候发生呢?我的意思是如果我声明一个这样的变量:

unsigned long current_time = millis();

void main() {
    while () {
        //some code using the current_time global variable 
    }
}

这里,全局变量初始化的确切时间很重要。请说出在这种情况下会发生什么。

【问题讨论】:

  • 所以了解您所说的语言可能会很有用...
  • C 语言。更具体地说,我倾向于使用 arduino 进行编程。

标签: c variables global-variables arduino


【解决方案1】:

由于您没有定义您所说的语言,我假设它是 C++。

在计算机编程中,全局变量是在每个范围内都可以访问的变量(除非有阴影)。与全局变量的交互机制称为全局环境(另请参见全局状态)机制。全局环境范式与本地环境范式形成对比,其中所有变量都是本地的,没有共享内存(因此所有交互都可以重新进行消息传递)。 Wikipedia.


原则上,定义在任何函数之外的变量(即全局变量、命名空间变量和类静态变量)会在调用 main() 之前进行初始化。翻译单元中的此类非局部变量按其声明顺序进行初始化(第 10.4.9 节)。如果此类变量没有显式初始化器,则默认将其初始化为其类型的默认值(第 10.4.2 节)。内置类型和枚举的默认初始值设定项值为 0。 [...] 不同翻译单元中全局变量的初始化顺序没有保证。因此,在不同编译单元的全局变量初始化器之间创建顺序依赖是不明智的。此外,不可能捕获由全局变量的初始化程序引发的异常(第 14.7 节)。通常最好尽量减少全局变量的使用,特别是限制需要复杂初始化的全局变量的使用。 See.

【讨论】:

    【解决方案2】:

    (快速回答:C 标准不支持这种初始化;您必须查阅编译器的文档。)

    现在我们知道语言是 C,我们可以看看标准对它的规定。

    C996.7.8 第4段:

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

    而 2011 年的新标准(至少是我的草案)说:

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

    因此,使用函数调用初始化静态对象(例如,像 current_time 这样的全局对象)是违反约束的。编译器可以拒绝它,或者它可以接受它并发出警告,如果它提供语言扩展,它可以做任何它喜欢的事情。

    C 标准没有说明初始化发生的时间,因为它不允许这种初始化。基本上,在main() 函数开始执行之前,您的任何代码都无法执行。

    显然您的编译器允许将此作为​​扩展名(假设您已实际编译此代码)。您必须查阅编译器的文档以了解语义是什么。

    (通常main 被声明为int main(void)int main(int argc, char *argv[]) 或等价物,或以某种实现定义的方式。在许多情况下,void main() 表示程序员从一本写得不好的书中学习了 C,其中有太多了。但这仅适用于托管实现。独立的实现,通常用于嵌入式系统,可以以任何他们喜欢的方式定义程序的入口点。由于您的目标是 Arduino,因此您可能正在使用独立的实现,并且你应该声明 main() 但是编译器的文档告诉你。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      • 2015-07-18
      • 1970-01-01
      相关资源
      最近更新 更多