关于C语言全局const变量初始化时机及调用主体的技术问询
嘿,我来帮你把这两个C语言的问题讲清楚:
问题1:const变量的初始化发生在什么时候?
const变量的初始化时机分两种情况,取决于它的作用域:
- 全局/静态const变量:
- 如果是编译期就能确定的常量(比如
const int MAX_NUM = 100;),会在程序加载阶段(main函数执行前),由操作系统或启动代码把预计算好的值直接写入对应的内存区域。 - 如果是需要运行时计算的(比如你问题里依赖函数返回值的
tab),会在全局构造阶段执行初始化——这个阶段依然在main()函数执行之前,由启动代码触发。
- 如果是编译期就能确定的常量(比如
- 局部const变量:
当程序执行进入它所在的代码块(比如函数内部的const int val = func();)时才会初始化,和普通局部变量的初始化时机一致,区别只是它的值一旦确定就无法修改。
问题2:全局const指针
tab的初始化调用者是谁? 先看你的代码片段:
static const uint32 *GetTableAddress(void) { if(memcmp(buf1, buf2, sizeof(buf1)) == 0) { return(&buf1); } else { return((uint32*)0x12345678); } } const uint32 *tab = GetTableAddress();
这里的tab是全局变量,而且它的初始化依赖GetTableAddress()的运行结果,属于运行时初始化,不是编译期就能确定的常量。
实际调用GetTableAddress()的是编译器生成的程序启动代码(通常叫CRT启动代码,比如crt0.o这类目标文件)。程序的启动流程大概是这样的:
- 操作系统把你的程序加载到内存中
- 执行CRT启动代码,它会遍历所有需要运行时初始化的全局变量列表,逐个执行它们的初始化逻辑——这里就是调用
GetTableAddress(),把返回值赋值给tab - 完成所有全局初始化后,才会调用
main()函数开始程序的主体逻辑
补充一句:因为GetTableAddress()是static修饰的,只能在当前C文件内访问,但启动代码不需要直接调用它的函数名——编译器会把这个初始化操作封装成一个匿名的小函数,放到全局初始化链表中,启动时自动执行这个链表上的所有函数。
内容的提问来源于stack exchange,提问作者omer ido
相关产品推荐
相关产品推荐

