使用字符串文字初始化构造函数中的std :: array <char,x>成员。 GCC错误?</char,x>

时间:2014-02-04 14:21:30

标签: c++ gcc c++11 compiler-bug stdarray

以下使用字符串文字在构造函数中初始化std::array <char, N>成员的示例不能在GCC 4.8上编译,而是使用Clang 3.4进行编译。

#include <iostream>
#include <array>

struct A {
  std::array<char, 4> x; 
  A(std::array<char, 4> arr) : x(arr) {}
};


int main() {
    // works with Clang 3.4, error in GCC 4.8.
    // It should be the equivalent of "A a ({'b','u','g','\0'});"
    A a ({"bug"});
    for (std::size_t i = 0; i < a.x.size(); ++i)
        std::cout << a.x[i] << '\n';

    return 0;
}

第一印象看起来像是一个GCC错误。我觉得它应该编译,因为我们可以直接用字符串文字初始化std::array<char, N>。例如:

std::array<char, 4> test = {"bug"}; //works

我很想看看标准对此有何看法。

1 个答案:

答案 0 :(得分:2)

是的,您的代码有效;这是gcc中的一个错误。

这是一个更简单的程序来演示错误(我用std::array<char, 4>替换了S并摆脱了A,因为我们可以在函数返回中演示错误(这使得分析更简单,因为我们不必担心构造函数重载):

struct S { char c[4]; };
S f() { return {"xxx"}; }

这里我们有一个类型为S的目标对象,它来自 braced-init-list {{1} copy-initialized (8.5p15)因此,对象是列表初始化(8.5p17b1)。 {"xxx"}是聚合(8.5.1p1),因此执行聚合初始化(8.5.4p3b1)。在聚合初始化中,成员S copy-initialized ,来自相应的 initializer-clause c(8.5.1p2)。我们现在返回到目标对象类型为"xxx"的8.5p17并初始化字符串文字char[4],因此8.5p17b3将我们引用到8.5.2并且"xxx"数组的元素被初始化为字符串的连续字符(8.5.2p1)。

注意gcc在复制初始化char时可以正常工作,同时打破各种形式的复制和直接初始化;参数传递(包括构造函数),函数返回,以及基础和成员初始化:

S s = {"xxx"};

最后一个特别有趣,因为它表明这可能与bug 43453有关。