什么时候发生全局变量的初始化?

时间:2012-01-03 18:56:43

标签: c variables global-variables arduino

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

unsigned long current_time = millis();

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

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

2 个答案:

答案 0 :(得分:3)

由于你没有定义你正在谈论的语言,我认为它是C ++。

  

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


  

原则上,在调用main()之前初始化在任何函数外部定义的变量(即全局,名称空间和类静态变量)。翻译单元中的此类非本地变量按其声明顺序初始化(第10.4.9节)。如果此类变量没有显式初始值设定项,则默认情况下将其初始化为其类型的默认值(第10.4.2节)。内置类型和枚举的默认初始化值为0. [...]在不同的转换单元中没有保证全局变量初始化的顺序。因此,在不同编译单元中创建全局变量的初始值设定项之间的顺序依赖关系是不明智的。此外,无法捕获全局变量初始化程序抛出的异常(第14.7节)。通常最好最小化全局变量的使用,特别是限制使用需要复杂初始化的全局变量。 See

答案 1 :(得分:2)

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

现在我们知道语言是C,我们可以看到标准对此有何看法。

C99 6.7.8第4段:

  

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

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

  

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

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

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

显然你的编译器允许这个作为扩展(假设你实际编译了这段代码)。您将不得不查阅编译器的文档以了解语义是什么。

(通常main声明为int main(void)int main(int argc, char *argv[])或等效,或者以某种实现定义的方式。在许多情况下void main()表示从中学习C的程序员一本写得不好的书,其中有太多。但这只适用于托管实现。独立实现,通常用于嵌入式系统,可以任意方式定义程序的入口点。既然你的目标是Arduino,你'可能使用一个独立的实现,你应该声明main()然而编译器的文档告诉你。)