2012-01-03 196 views
2

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

unsigned long current_time = millis(); 

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

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

+1

因此,它可能是有用的知道你在说什么语言... – asawyer 2012-01-03 18:59:21

+0

C languange。更具体地说,我倾向于编程arduino。 – 2012-01-03 21:08:19

回答

2

由于您没有定义您正在讨论的语言,因此我将其假定为C++。

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


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

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(),但是编译器的实现文档告诉你。)