1

我知道未初始化的静态变量存储在 BSS 中,因此保证用 all 初始化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. 这是保证/定义的行为吗?


注意:我知道存在关于静态变量初始化和未初始化静态变量的默认值的 Stack Overflow 问题;我无法找到有关此“部分初始化”的现有问题(如果我所描述的内容存在现有的、更正确的术语,请告诉我)。

4

1 回答 1

3

所有剩余元素都初始化为零(对于算术类型)或空指针(对于指针)。C 2018 6.7.9 21 说:

如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化与具有静态存储持续时间的对象相同。

6.7.9 10 说具有静态存储持续时间的对象实际上是用零初始化的:

…如果一个具有静态或线程存储持续时间的对象没有被显式初始化,那么:

— 如果它具有指针类型,则将其初始化为空指针;

— 如果它具有算术类型,则将其初始化为(正或无符号)零;

— 如果是聚合,则每个成员都根据这些规则(递归地)初始化,并且任何填充都被初始化为零位;

— 如果是联合,则根据这些规则(递归)初始化第一个命名成员,并将任何填充初始化为零位;

于 2020-01-28T21:30:13.080 回答