C 聚合子对象的隐式初始化

C 聚合子对象的隐式初始化,c,struct,initialization,aggregate,language-lawyer,C,Struct,Initialization,Aggregate,Language Lawyer,当查看N2310中聚合的初始化规则时,我发现以下段落(emp.mine): 6.7.9(第19页): 初始化应按初始化器列表顺序进行,每个 为覆盖任何子对象的特定子对象提供的初始值设定项 以前列出的同一子对象的初始值设定项;154)全部 未明确初始化的子对象应进行初始化 与具有静态存储持续时间的对象隐式相同。 6.7.9(第21页): 如果括号内的列表中的初始值设定项少于 是集合的元素或成员,或集合中的字符数较少 用于初始化已知大小的数组的字符串文字 是数组中的元素,骨料的剩余部分应为 与具有静

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

6.7.9(第19页)

初始化应按初始化器列表顺序进行,每个 为覆盖任何子对象的特定子对象提供的初始值设定项 以前列出的同一子对象的初始值设定项;154)全部 未明确初始化的子对象应进行初始化 与具有静态存储持续时间的对象隐式相同。

6.7.9(第21页)

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

在我看来,
6.7.9(第19页)
意味着
6.7.9(第21页)
(但反之亦然)。例如:

#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
}
#包括
结构测试{
INTA;
int b;
INTC;
};
int main(){
结构测试={
.a=123
};
printf(“%d%d%d\n”,test.a,test.b,test.c);//显然,12300已经打印出来了
}
我认为这种情况可以用
6.7.9(第19页)
6.7.9(第21页)


6.7.9(第21页)
的目的是什么?我遗漏了什么?

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;
}
或者其他程序

#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;
}
所以

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


第二个引文是在C标准中采用指定的初始值设定人之前就存在的,它描述了如下情况

char s[20] = "Hello";

并回答是否将初始化字符数组的尾部的问题。它保持与C++标准的兼容性,在指定的初始化器之前,C++ 17标准不存在。< /P>“指定的初始化器不存在直到C++ 17标准”。“C++ 20是用来代替C++ 17的?@ L.F。它们在C++ 17标准草案中描述。如果我能正确地理解你,关键是第二个引号与
初始值设定项列表无关,而第一个引号与之相关。对吗?@SomeName否这两个引号都处理初始值设定项列表。但第一个引文描述了聚合元素在两个指定初始值设定项之间或在一个指定初始值设定项之前没有显式初始值设定项的情况。第二个引号描述了当初始化的数据成员之间没有间隙,但没有足够的初始值设定项用于所有元素时的情况。@SomeName在本例中,两个引号都被应用。
0 0 0 0 4 0 0 0 0 9
char s[20] = "Hello";