我知道当程序运行时,首先执行main()函数。但是,在main()之外声明的全局变量的初始化何时发生?我的意思是如果我像这样声明一个变量:
unsigned long current_time = millis();
void main() {
while () {
//some code using the current_time global variable
}
}
这里,全局变量初始化的确切时间很重要。
因为你没有定义你所说的语言,所以我假设它是c++。
在计算机编程中,全局变量是在每个作用域中都可以访问的变量(除非有阴影)。与全局变量的交互机制称为全局环境(另见全局状态)机制。全局环境范型与局部环境范型形成对比,在局部环境范型中,所有变量都是局部的,没有共享内存(因此所有交互都可以重定向到消息传递中)。维基百科。
原则上,在任何函数之外定义的变量(即全局变量、命名空间变量和类静态变量)都在main()调用之前初始化。翻译单元中的非局部变量按声明顺序初始化(§10.4.9)。如果这样的变量没有显式初始化式,则默认初始化为其类型的默认值(§10.4.2)。内置类型和枚举的默认初始化项值为0。[…在不同的翻译单元中,全局变量的初始化顺序没有保证。因此,在不同编译单元的全局变量的初始化式之间创建顺序依赖是不明智的。此外,不可能捕获由全局变量的初始化器抛出的异常(第14.7节)。通常最好尽量减少全局变量的使用,特别是限制需要复杂初始化的全局变量的使用。明白了。
(快速回答:C标准不支持这种初始化;你必须查阅编译器的文档)
既然我们知道这门语言是C语言,我们就可以看看标准是怎么说的了。
C99 6.7.8段落4:
具有static的对象的初始化式中的所有表达式存储持续时间应为常量表达式或字符串字面值。
2011年的新标准(至少草案I有)说:
具有static的对象的初始化式中的所有表达式存储持续时间应为常量表达式或字符串字面值。
因此,用函数调用初始化静态对象(例如,全局对象,如current_time
)是违反约束的。如果它提供了语言扩展,编译器可以拒绝它,也可以接受它并给出警告,然后做任何它喜欢的事情。
C标准没有说明初始化何时发生,因为它不允许这种初始化。在main()
函数开始执行之前,基本上没有代码可以执行。
显然你的编译器允许这作为一个扩展(假设你已经编译了这段代码)。你必须查阅编译器的文档来了解语义是什么。
(通常main
被声明为int main(void)
或int main(int argc, char *argv[])
或等价的,或以某种实现定义的方式。在许多情况下,void main()
表示程序员是从一本写得很差的书中学习C的,这样的书太多了。但这只适用于托管实现。独立实现(通常用于嵌入式系统)可以任意定义程序的入口点。因为你的目标是Arduino,你可能会使用一个独立的实现,你应该声明main()
,但编译器的文档告诉你。)