首页 > 解决方案 > 聚合子对象的隐式初始化

问题描述

在查看 N2310 中聚合的初始化规则时,我发现了以下段落(emp. mine):

6.7.9(p19)

初始化应按初始化程序列表顺序进行,为特定子对象提供的每个初始化程序都将覆盖同一子对象的任何先前列出的初始化程序;154)所有 未显式初始化的子对象都应 隐式初始化,与具有静态存储持续时间的对象相同。

6.7.9(p21)

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

在我看来,这6.7.9(p19)意味着6.7.9(p21)(但反之亦然)。例如:

#include <stdio.h>

struct test{
    int a;
    int b;
    int c;
};

int main(){
    struct test test = {
        .a = 123
    };

    printf("%d%d%d\n", test.a, test.b, test.c); //obviously, 12300 is printed
}

我认为这种情况可以由两者来6.7.9(p19)解释6.7.9(p21)

目的是6.7.9(p21)什么?我错过了什么?

标签: cstructinitializationaggregatelanguage-lawyer

解决方案


6.7.9 考虑了所谓的指定初始化器。

考虑以下演示程序

#include <stdio.h>

struct test{
    int a;
    int b;
    int c;
};

int main(void) 
{
    struct test test = {
        .c = 123
    };

    printf("%d %d %d\n", test.a, test.b, test.c);

    return 0;
}

它的输出是

0 0 123

或者其他程序

#include <stdio.h>

int main(void) 
{
    enum { N = 10 };
    int a[N] = { [0] = 0, [4] = 4, [9] = 9 };

    for ( size_t i = 0; i < N; i++ ) printf( "%d ", a[i] );
    putchar( '\n' );

    return 0;
}

它的输出是

0 0 0 0 4 0 0 0 0 9

所以

所有未显式初始化的子对象都应隐式初始化,与具有静态存储持续时间的对象相同

第二个引用在 C 标准中采用指定的初始化器之前就已经存在,并描述了例如这样的情况

char s[20] = "Hello";

并回答字符数组的尾部是否会被初始化的问题。它保持与 C++ 标准的兼容性,在 C++ 17 标准之前指定的初始化程序不存在。


推荐阅读