这个编译器错误是由无效代码触发的,还是应该编译?

时间:2014-08-02 16:18:00

标签: c++ c++11 g++ clang++ g++4.8

鉴于以下完整计划:

#include <functional>

struct jobbie
{
    std::function<void()> a;
};

void do_jobbie(jobbie j = {})
{
    if (j.a) 
        j.a();
}

int main()
{
    do_jobbie();
    return 0;
}

在gcc上编译它(Ubuntu 4.8.1-2ubuntu1~12.04)4.8.1: 吊杆!

richard@DEV1:~/tmp$ g++ -std=c++11 bug.cpp
bug.cpp: In function ‘int main()’:
bug.cpp:16:13: internal compiler error: in create_tmp_var, at gimplify.c:479
  do_jobbie();
             ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.8/README.Bugs> for instructions.
Preprocessed source stored into /tmp/ccWGpb7M.out file, please attach this to your bugreport.

然而,clang [Apple LLVM版本5.1(clang-503.0.40)(基于LLVM 3.4svn)]对此感到满意。

$ clang++ -std=c++11 bug.cpp

在我看来,clang正确地推断出j默认为默认构造的jobbie对象,而gcc(显然)正在爆炸。

void do_jobbie(jobbie j = jobbie {})替换第8行修复了gcc上的问题。

问题 - 这些是真的:

  1. clang是正确的,gcc是错误的(忽略编译器爆炸)
  2. clang超出了标准,它不应该真正编译
  3. 标准没有说清楚?

2 个答案:

答案 0 :(得分:4)

内部编译器错误始终是编译器错误。编译器应该能够处理任何事情,而不会像那样崩溃。

clang在崩溃时有类似的处理方式,生成用于报告错误的数据,并将用户指向clang的错误报告网页。

我对这段代码没有任何疑问。对我来说,它应该编译并运行似乎很简单。

答案 1 :(得分:2)

这表明它应该有效:

  

使用复制初始化语义,默认参数与参数类型变量声明中的初始化程序具有相同的语义约束。

(8.3.6,来自n3936草案的措辞)