我知道未初始化的静态变量存储在BSS中,因此保证可以使用所有0
(针对它们各自的数据类型大小)进行初始化。
此外,在C语言中,可以将静态变量定义为编译时常量(仅)。
“部分初始化”静态变量的定义行为是什么(我不确定这是否是正确的术语),如下所示:
// main.c
#include <stdbool.h>
#include <stdio.h>
static struct Foo
{
bool f[2][3];
} g_table = { { { true, true, false },
{ true } } };
int main( int argc, char* argv[] )
{
printf( "%d %d %d\n", g_table.f[0][0], g_table.f[0][1], g_table.f[0][2] );
printf( "%d %d %d\n", g_table.f[1][0], g_table.f[1][1], g_table.f[1][2] );
return 0;
}
。
$ gcc --version && gcc -g ./main.c && ./a.out
gcc (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1 1 0
1 0 0
通过上面的“部分初始化”,我的意思是指g_table
的初始化,其中并非明确定义成员数组的所有元素。上面的示例暗示表示静态对象g_table
的未明确初始化的部分已初始化为0
。 这是保证的/已定义的行为吗?
注意:我知道关于静态变量初始化和未初始化静态变量的默认值,存在堆栈溢出问题。我找不到有关此“部分初始化”的现有问题(请让我知道,对于我所描述的内容是否存在现有的,更正确的术语)。
答案 0 :(得分:3)
所有剩余元素都初始化为零(对于算术类型)或空指针(对于指针)。 C 2018 6.7.9 21说:
如果用大括号括起来的列表中的初始化程序少于聚合中的元素或成员,或者用于初始化已知大小的数组的字符串文字中的字符少于该数组中的元素,则其余聚合应与具有静态存储持续时间的对象隐式初始化。
6.7.9 10说,具有静态存储持续时间的对象实际上是用零初始化的:
…如果未明确初始化具有静态或线程存储持续时间的对象,则:
-如果具有指针类型,则将其初始化为空指针;
-如果具有算术类型,则将其初始化为(正数或无符号)零;
-如果是聚合,则根据这些规则(递归地)初始化每个成员,并将任何填充初始化为零位;
-如果是联合,则将根据这些规则(递归)初始化第一个命名成员,并将任何填充初始化为零位;