鉴于以下完整计划:
#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上的问题。
问题 - 这些是真的:
答案 0 :(得分:4)
内部编译器错误始终是编译器错误。编译器应该能够处理任何事情,而不会像那样崩溃。
clang在崩溃时有类似的处理方式,生成用于报告错误的数据,并将用户指向clang的错误报告网页。
我对这段代码没有任何疑问。对我来说,它应该编译并运行似乎很简单。
答案 1 :(得分:2)
这表明它应该有效:
使用复制初始化语义,默认参数与参数类型变量声明中的初始化程序具有相同的语义约束。
(8.3.6,来自n3936草案的措辞)