VC++14 中数组 Value-Initialization 的内部编译器错误 (VS2015)
Internal Compiler Error on Array Value-Initialization in VC++14 (VS2015)
我在 Visual Studio 2015 CTP 6 上得到了一个 ICE。不幸的是,这是在一个大项目中发生的,我不能 post 这里的整个代码,我一直无法在最小样本上重现问题。我希望得到的是帮助构建这样的示例(提交给 Microsoft)或者可能说明正在发生的事情 and/or 我做错了什么。
这是我正在做的 mock-up。 (请注意,我在这里展示的代码 不会 生成 ICE;我只是用这个简单的例子来解释这种情况。)
我有一个不可复制的 class A
(它有几个 "reference" 成员)并且没有默认构造函数。另一个 class、B
包含一个 A
数组(A
值的普通 C 数组,没有 references/pointers),我正在初始化这个数组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 问题 和 获取索引(使用变量构造,使用数组访问,)但我认为这会导致 "undefined behavior" 看起来很费解。
上面的示例和我的实际代码之间的明显区别(除了比例)是 A
和 B
是 classes 而不是结构,每个都是 declared/defined 在它自己的 source/header 文件对中,并且构造函数的 none 是内联的。 (我复制了这些,但仍然无法重现 ICE。)
对于我的实际项目,我尝试清理构建的文件并重建,但无济于事。有什么建议等吗?
P.S。我不确定我的标题是否合适。有什么建议吗?!?!
更新 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,引用或指针或值类型,...)
这意味着我对我的问题有某种解决方案,虽然我的内部 class 布局对我和这个应用程序很重要,但我可以容忍性能下降(由于缓存丢失导致一些热数据与其他数据分开)以解决这个问题。
但是,我仍然非常喜欢能够提交给 Microsoft 的 ICE 的最小复制。我不想在接下来的两年里一直受困于此(至少!)
UPDATE 4: 我已经试过 VS2015 RC 并且 ICE 仍然存在(虽然错误消息指的是不同的内部代码行,相同的第 247 行 "main.c" 文件。)
而且我已经开了一个bug report on Microsoft Connect。
我确实向微软报告了这个问题,在与他们分享了我的一些项目代码后,问题似乎已经被追踪并修复。他们说修复将包含在最终的 VC14 版本中。
感谢您的评论和指点。
我在 Visual Studio 2015 CTP 6 上得到了一个 ICE。不幸的是,这是在一个大项目中发生的,我不能 post 这里的整个代码,我一直无法在最小样本上重现问题。我希望得到的是帮助构建这样的示例(提交给 Microsoft)或者可能说明正在发生的事情 and/or 我做错了什么。
这是我正在做的 mock-up。 (请注意,我在这里展示的代码 不会 生成 ICE;我只是用这个简单的例子来解释这种情况。)
我有一个不可复制的 class A
(它有几个 "reference" 成员)并且没有默认构造函数。另一个 class、B
包含一个 A
数组(A
值的普通 C 数组,没有 references/pointers),我正在初始化这个数组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 问题 和 获取索引(使用变量构造,使用数组访问,)但我认为这会导致 "undefined behavior" 看起来很费解。
上面的示例和我的实际代码之间的明显区别(除了比例)是 A
和 B
是 classes 而不是结构,每个都是 declared/defined 在它自己的 source/header 文件对中,并且构造函数的 none 是内联的。 (我复制了这些,但仍然无法重现 ICE。)
对于我的实际项目,我尝试清理构建的文件并重建,但无济于事。有什么建议等吗?
P.S。我不确定我的标题是否合适。有什么建议吗?!?!
更新 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,引用或指针或值类型,...)
这意味着我对我的问题有某种解决方案,虽然我的内部 class 布局对我和这个应用程序很重要,但我可以容忍性能下降(由于缓存丢失导致一些热数据与其他数据分开)以解决这个问题。
但是,我仍然非常喜欢能够提交给 Microsoft 的 ICE 的最小复制。我不想在接下来的两年里一直受困于此(至少!)
UPDATE 4: 我已经试过 VS2015 RC 并且 ICE 仍然存在(虽然错误消息指的是不同的内部代码行,相同的第 247 行 "main.c" 文件。)
而且我已经开了一个bug report on Microsoft Connect。
我确实向微软报告了这个问题,在与他们分享了我的一些项目代码后,问题似乎已经被追踪并修复。他们说修复将包含在最终的 VC14 版本中。
感谢您的评论和指点。