以下程序编译时没有错误。
有趣的是,当我设置
我知道全局变量只能用常量表达式来初始化。 我也知道可以在C标准的第6.6p7节中指定可用于全局初始化程序的常量表达式类型:
更多自由度允许在初始化程序中使用常量表达式。 这样的常量表达式应为以下之一或求值为以下之一: - 算术常量表达式, - 空指针常量, - 地址常量,或 - 完整对象类型的地址常量加上或减去整数常量表达式。
请注意,允许地址常量减去整数常量,但不允许地址常量减去另一个地址常量。
问题:
为什么C标准限制了初始化全局变量的方式?是什么阻止C标准接受“unsigned long my_addr = (unsigned long)addr_b - (unsigned long)addr_a”这样的初始化方式?
你为什么想要这个?
假设
#include <stdio.h>
char addr_a[8];
char addr_b[8];
unsigned long my_addr = (unsigned long)addr_b - 8; // PASS
// unsigned long my_addr = (unsigned long)addr_b - (unsigned long)addr_a; // FAIL (error: initializer element is not constant)
int main() {
printf("%lx\n", my_addr);
return 0;
}
有趣的是,当我设置
unsigned long my_addr = (unsigned long)addr_b - (unsigned long)addr_a
时,编译器会抛出“error:initializer element is not constant”的错误。我知道全局变量只能用常量表达式来初始化。 我也知道可以在C标准的第6.6p7节中指定可用于全局初始化程序的常量表达式类型:
更多自由度允许在初始化程序中使用常量表达式。 这样的常量表达式应为以下之一或求值为以下之一: - 算术常量表达式, - 空指针常量, - 地址常量,或 - 完整对象类型的地址常量加上或减去整数常量表达式。
请注意,允许地址常量减去整数常量,但不允许地址常量减去另一个地址常量。
问题:
为什么C标准限制了初始化全局变量的方式?是什么阻止C标准接受“unsigned long my_addr = (unsigned long)addr_b - (unsigned long)addr_a”这样的初始化方式?
你为什么想要这个?
假设
addr_a
和addr_b
分别表示.text
部分的开始和结束。程序可能想要映射.text
部分,其大小为(unsigned long)addr_b - (unsigned long)addr_a
。trusted-firmware-a项目在Boot Loader stage 2(BL2)中执行此操作。请参见BL_CODE_END - BL_CODE_BASE
,该代码用于arm_bl2_setup.c。