【问题标题】:Internal Compiler Error on Array Value-Initialization in VC++14 (VS2015)VC++14(VS2015)中数组值初始化的内部编译器错误
【发布时间】:2015-05-23 19:56:25
【问题描述】:

我在 Visual Studio 2015 CTP 6 上获得了 ICE。不幸的是,这发生在一个大型项目中,我无法在此处发布整个代码,而且我无法在最小示例上重现该问题.我希望得到的是帮助构建这样一个样本(提交给微软),或者可能是关于正在发生的事情和/或我做错了什么的启发。

这是我正在做的模型。 (请注意,我在此处提供的代码不会生成 ICE;我只是使用这个简单的示例来解释这种情况。)

我有一个类A,它是不可复制的(它有几个“引用”成员)并且没有默认构造函数。另一个类B 拥有一个As 数组(A 值的普通C 数组,没有引用/指针),我正在使用统一初始化语法在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 来包含As .

请注意,如果我不使用数组并使用单个变量(例如 A a0, a1, a2;,我可以这样做,因为数组很小且大小固定) ) ICE 消失。但这不是我想要的,因为我将失去通过索引获取它们的能力,这是我需要的。我可以在数组上使用松散变量的联合来解决我的 ICE 问题获取索引(使用变量构造,使用数组访问),但我认为这会导致“未定义的行为”并且看起来很复杂。

上述示例和我的实际代码(除了比例)之间的明显区别是AB 是类而不是结构,每个都在其自己的源/头文件对中声明/定义,并且没有一个构造函数是内联的。 (我复制了这些,但仍然无法重现 ICE。)

对于我的实际项目,我尝试清理构建的文件并重新构建,但无济于事。有什么建议吗?

附:我不确定我的标题是否合适。有什么建议吗?!?!

更新 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 行。 )

我开了一个bug report on Microsoft Connect

【问题讨论】:

  • A有B,B有A,你确定需要这么乱的组织吗?
  • 一个 ICE 并不一定意味着由于编译器中的错误而无法编译代码。有时这意味着您正在使用编译器当前无法正常处理的某些功能组合。尝试遵循here提供的建议。
  • 获取 ICE 的原始源代码。 Makr 源代码控制架。现在,删除一堆你认为不相关的东西。编译。冰?架子,重复。没有冰?搁置,备份,移除不同的东西。重复。如果你选择了足够多无关紧要的东西,你可以通过这种方式让你的例子变得非常小。请记住,您的目标是编译,不是链接:链接器错误是正常的!
  • @StraightLine:每个B 包含一些As,每个A 都有一个指向包含它的B 的指针。我看不到“混乱”。无论如何,这不是原因。
  • @HadiBrais:谢谢,我会调整优化选项并回复您。不过,我并不期待任何事情,因为它也在 Debug 中使用 ICE。在一个离题的注释上,您链接到的页面引用了一篇仅适用于 VC6 及更早版本的知识库文章! VC6 是什么,现在已经 17 岁了?!它在谈论一个“MS-DOS 会话”,这是一个死的赠品!

标签: c++ c++11 visual-studio-2015 array-initialization internal-compiler-error


【解决方案1】:

我确实向微软报告了这个问题,在与他们分享了我的一些项目代码后,似乎问题已被追踪并修复。他们说修复将包含在最终的 VC14 版本中。

感谢cmets和指点。

【讨论】:

    猜你喜欢
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    相关资源
    最近更新 更多