来自C99标准中的6.7.8.10:
如果没有显式初始化具有自动存储持续时间的对象,则其值为 不定。如果未明确初始化具有静态存储持续时间的对象, 然后:
- 如果它有指针类型,则将其初始化为空指针;
- 如果它有算术类型,则初始化为(正或无符号)零;
- 如果是聚合,则根据这些规则初始化(递归)每个成员;
- 如果是联合,则根据这些初始化(递归)第一个命名成员 规则。
任何类型的全局变量(数组,结构,位域)是否始终定义为static storage
?
答案 0 :(得分:4)
是否可以保证全局变量始终用c99初始化为0?
是和否
static void *g_v_ptr; // initialized to a null pointer
C99详细说明了值,但没有详细说明。 "它有指针类型,它被初始化为空指针"意味着指针具有空指针的值。这可能是NULL
,也可能不是0
。这可能是g_v_ptr == NULL
,也可能不是g_v_ptr == 0
。编译器可能有许多与空指针对应的位模式。在任何情况下,0
都是正确的{{1}},但指针可能具有与{{1}}不同的位表示。当然,所有零位的模式通常易于实现,当然也是最可能的实现。然而,规范只是软弱到足以允许使用一些非零位模式。
可以对浮点数进行类似的处理。
在任何情况下(IAC),初始化值等于为0.
答案 1 :(得分:3)
根据C标准(5.1.2执行环境)
1定义执行环境:独立和托管。在 两种情况下,程序启动发生在指定的C函数时 由执行环境调用。 具有静态存储的所有对象 持续时间应在之前初始化(设置为初始值) 程序启动。这种初始化的方式和时间是 否则没有特别说明。程序终止将控制权返回给 执行环境。
和(6.2.4对象的存储持续时间)
3在没有存储类的情况下声明其标识符的对象 指定_Thread_local,与外部或内部链接 或者使用存储类指定静态,具有静态存储 持续时间。它的生命周期是程序及其执行的整个过程 在程序启动之前,存储的值只初始化一次。
答案 2 :(得分:2)
是。这是有保证的(至少从C89开始)。 “全局变量”(具有内部或外部链接)具有静态存储持续时间。根据C99,6.7.8初始化,保证任何具有静态存储的对象都为零。
C99 draft, 6.2.4 Storage durations of objects:
3一个对象,其标识符用外部或内部声明 链接,或与存储类说明符静态存储 持续时间。它的生命周期是整个程序及其执行 在程序启动之前,存储的值只初始化一次。
6.2.2 Linkages of identifiers描述了标识符的链接,特别是与“全局”变量的关联:
3如果对象或函数的文件范围标识符的声明包含静态的存储类说明符,则标识符具有内部链接.22)
4对于在范围内使用存储类说明符extern声明的标识符,其中该标识符的先前声明是可见的,23)如果先前声明指定内部或外部链接,则在后面的声明中标识符的链接与先前声明中指定的链接相同。如果没有先前声明可见,或者先前声明未指定链接,则标识符具有外部链接。
忽略could lead to undefined behaviour的情况,所有文件范围标识符都具有内部或外部链接,并且它们都具有静态存储持续时间。
答案 3 :(得分:0)
是的,只要它们存储在bss
部分。
您的链接描述文件定义它并且(主要)默认链接描述文件执行此操作。 虽然您可以手动将数据手动存储在不同的部分,也可以使用全局范围的变量。
BTW是负责将该部分归零的启动代码。如果您使用的是非标准平台,或者您的启动代码是由您制作的,则必须确保这一点。