【问题标题】:C++20 Designated Initializers char[]C++20 指定初始值设定项 char[]
【发布时间】:2020-07-20 08:53:39
【问题描述】:

C++20 introduces designated initialisers。我正在尝试使用新语法初始化结构内的字符数组。

Pretty simple problem, I think code may explain it best:

struct Test
{
    unsigned v;
    char b[12];
};

int main()
{
    char str[12] = "hello"; // Works.
    char strb[12]{"hello"}; // Works.
    //
    Test testa
    {
        .v = 100u,
        .b = "hello" //Doesn't work...
    };
    Test testb
    {
        .v = 100u,
        .b = { "hello" } //Doesn't work...
    };
    Test testc
    {
        .v{ 100u },
        .b{ "hello" } //Doesn't work...
    };
    Test testd
    {
        .v{ 100u },
        .b{ "hello" } //Doesn't work...
    };
    Test teste
    {
        .v = 100u,
        .b = {} //This works.
    };
    Test testf
    {
        .v = 100u,
        .b = {'h', 'e', 'l', 'l', 'o', '\0'} //This works.
    };
    return 0;
}

我发现了这种行为 bazzar,char str[12] = "hello"; 行工作得很好。但是相同的初始化形式在指定的初始化列表中不起作用。

问题: 为什么我不能用字符串字面量初始化 char 数组?

编辑

我之前使用的是 GCC。 This works with clang. GCC 是否有解决方法,clang 或 GCC 是否正确?

【问题讨论】:

  • ... 所以 GCC 拒绝 Test testa { .v = 100u, .b = "hello" }; 但在非迂腐模式下接受 Test testa { .v = 100u, { .b = "hello" } };,这显然是荒谬的。
  • 有趣,对我来说听起来像是编译器错误...感谢相关链接!

标签: c++ initialization language-lawyer c++20 designated-initializer


【解决方案1】:

指定初始化器是aggregate initialization 的一个小变体。指示符名称的唯一用途是决定从给定的大括号或等号初始化程序中初始化哪个聚合成员。指定初始化的使用不会改变初始化的具体形式,因此也不会改变它是否有效。

鉴于您的 Test 对象,Test{100u, "hello"}Test{.v = 100u, .b = "hello"} 要么都有效,要么都无效。在这两种情况下,Test::b 都会按照[dcl.init.aggr]4.2 进行初始化:

否则,元素从相应的初始化子句复制初始化,或者使用相应的指定初始化子句的大括号或相等初始化子初始化。

复制初始化与您简单地初始化一个数组变量的过程完全相同。这是完全有效的。

所以你的可能应该工作。这是一个编译器错误。

GCC 的“解决方法”是等待错误被修复。或者回到标准聚合初始化,直到他们的编译器被修复。

【讨论】:

  • 我希望我错了,可以继续前进。我投了赞成票,但有人可能有一个有趣的句法工作,所以我会延迟选择你的答案:)
【解决方案2】:

我会说你不能这样初始化它,因为它们的类型不兼容。好吧,如果从严格的角度来看......或“迂腐”的水平;)

char 数组不等于 std::string,即使它们密切相关。为了类型安全,编译器不允许这样的赋值。
甚至 char array and char* are not identical,正如 Geeks for Geeks 所解释的那样。

我在这里看不到任何荒谬的东西......可能有什么我忽略了?

您在底部的“注释”部分中发布的规范:

在 C 中,大小比字符串字面量小一的字符数组可以从字符串字面量初始化;结果数组不是以空值结尾的。这在 C++ 中是不允许的。

我认为这可以解释它。但我同意,它有点“隐藏”。

【讨论】:

  • 谢谢。但我不是在谈论 std::string,只是在谈论 char 数组。我相信引号仅指初始化带有字符串文字的数组,这些字符串会因初始化而丢弃其空字符。因此,当删除 null 时,C++ 不允许初始化 char 数组。
  • 我提到 std:string 是因为您用于初始化的字符串文字并怀疑类型不匹配,因为 gcc 可以将 char[] b 和 "hello" 解释为类型 和 ans 因此阻止了该初始化...但这实际上与您发布的 C++20 规范相矛盾...我一无所知,实际上已删除了我的帖子。不知道为什么它仍然弹出。不过,感谢您的客气话和解释。
猜你喜欢
  • 2020-01-13
  • 2020-01-13
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
  • 2016-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多