奇怪的GCC数组初始化行为

时间:2014-06-24 05:24:18

标签: c++ gcc

在查看其他问题时,我遇到了此代码的变体(原始代码使用了std::thread代替std::vector,但语法相同):

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
    std::vector<double> vecs[10] = std::vector<double>(10, 1);
    for(auto& vec: vecs){
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<double>(std::cout, " "));
        std::cout<<std::endl;
    }
    return 0;
}

此代码不应编译; std::vector<double> vecs[10] = std::vector<double>(10, 1);不是有效的初始化语法,并且clang拒绝它error: array initializer must be an initializer list。但是,GCC accepts it似乎用指定的临时副本初始化列表中的每个向量。

这是一些我从未听说过的GCC扩展(以某种方式设法生存-pedantic-errors)或只是一个普通的错误吗?

2 个答案:

答案 0 :(得分:4)

我认为这是一个错误。

#include <vector>

int main()
{
  std::vector<double> x = std::vector<double>(10, 1);
  std::vector<double> vecs[10] = x;
  return 0;
}

作品(正如你所发现的那样)。

虽然

int main()
{
  int x = 10;
  int is[10] = x;
  return 0;
}

产生(预期)错误。

答案 1 :(得分:2)

进一步调查:

struct A { A() { } };
int main() { A a[10] = A(); }

这在GCC中编译。

struct A { A() = default; };
int main() { A a[10] = A(); }

也可以在GCC 4.9中编译,但不是我测试的早期版本(4.6-4.8)。

struct A { };
int main() { A a[10] = A(); }

不编译。

struct B { virtual ~B() { } };
struct A : B { };
int main() { A a[10] = A(); }

编译。

struct B {  ~B() { } };
struct A : B { };
int main() { A a[10] = A(); }

不编译。

我认为可以肯定地说这是一个错误。没有理智的扩展会有这种行为。请注意,第二种情况和第三种情况中的A都是POD类型(唯一的区别是显式默认的默认构造函数),但GCC 4.9对它们的处理方式不同。

编辑:再次通过GCC bugzilla,this bug report似乎是相关的。看起来我第一次错过了,因为标题是在谈论字符串文字。