我在 Visual Studio 2015 CTP 6 上获得了 ICE。不幸的是,这发生在一个大型项目中,我无法在此处发布整个代码,而且我无法在最小样本上重现该问题。我希望得到的是帮助构建这样一个样本(提交给微软),或者可能是关于正在发生的事情和/或我做错了什么的启发。
这是我正在做的事情的模型。(请注意,我在这里展示的代码不会生成 ICE;我只是使用这个简单的示例来解释这种情况。)
我有一个A
不可复制的类(它有几个“引用”成员)并且没有默认构造函数。另一个类,B
包含一个A
s 数组(纯 CA
值数组,没有引用/指针),我在B
使用统一初始化语法的构造函数中初始化这个数组。请参阅下面的示例代码。
struct B;
struct A
{
int & x;
B * b;
A (B * b_, int & x_) : x (x_), b (b_) {}
A (A const &) = delete;
A & operator = (A const &) = delete;
};
struct B
{
A a [3];
int foo;
B ()
: a {{this,foo},{this,foo},{nullptr,foo}} // <-- THE CULPRIT!
, foo (2)
{ // <-- This is where the compiler says the error occurs
}
};
int main ()
{
B b;
return 0;
}
我不能使用std::array
,因为我需要在它们的最终位置构造元素(不能复制。)我不能使用std::vector
,因为我需要B
包含A
s。
请注意,如果我不使用数组并使用单个变量(例如A a0, a1, a2;
,我可以这样做,因为数组很小且大小固定),ICE 就会消失。但这不是我想要的,因为我将失去通过索引获取它们的能力,这是我需要的。我可以在数组上使用松散变量的联合来解决我的 ICE 问题并获得索引(使用变量构造,使用数组访问),但我认为这会导致“未定义的行为”并且看起来很复杂。
上面的示例和我的实际代码(除了比例)之间的明显区别是,A
并且B
是类而不是结构,每个都在自己的源/头文件对中声明/定义,并且没有一个构造函数是内联的。(我复制了这些,但仍然无法重现 ICE。)
对于我的实际项目,我尝试清理构建文件并重建,但无济于事。有什么建议之类的吗?
PS我不确定我的标题是否合适。有什么建议吗?!?!
更新 1:这是 C1001 致命错误消息中引用的编译器文件:(compiler file 'f:\dd\vctools\compiler\utc\src\p2\main.c', line 230)
.
更新 2:由于我忘记提及,代码库在 C++14 模式下的 GCC 4.9.2 下干净(且正确)编译。
另外,我正在编译禁用所有优化。
更新3:我发现如果我重新排列成员数据B
并将数组放在最后,代码就会编译。我尝试了其他几种排列方式,它有时会编译,有时不会。我看不到任何关于在数组之前出现的其他成员使编译器完全运行 ICE 的模式!(作为 UDT 或原语,是否有构造函数,是否有 POD,引用或指针或值类型,...)
这意味着我对我的问题有某种解决方案,虽然我的内部类布局对我和这个应用程序很重要,但我可以容忍性能损失(由于将一些热数据与其他数据分开导致缓存未命中)克服这件事。
但是,我仍然非常喜欢能够提交给 Microsoft 的 ICE 的最小复制品。我不想在接下来的两年里被这个困住(至少!)
更新 4:我已经尝试过 VS2015 RC 并且 ICE 仍然存在(尽管错误消息指的是不同的内部代码行,即同一“main.c”文件中的第 247 行。)