You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS 15.5.6 C++编译器接受非法初始化代码是否属Bug?

Is this a Visual Studio C++ Compiler Bug?

没错,这确实是Visual Studio 15.5.6版本C编译器的bug,属于不符合C14标准的错误行为,具体原因和分析如下:

代码核心问题拆解

你的代码里,Foo类仅定义了一个接受两个参数的构造函数,但在Bar类中,你尝试用包含三个元素的初始化列表去初始化Foo<type>类型的成员f:

#include <string>
template<class type>
class Foo {
public:
    Foo(type x, std::string y) : x(x) , y(y) {}
    type x;
    std::string y;
};

template<class type>
class Bar {
public:
    // 此处初始化完全不符合C++标准规则
    Foo<type> f = { 1, 2, 3 };
};

int main() {
    Bar<double> b;
    // 运行时会触发未定义行为
}

当实例化Bar<double>时,Foo<double>的构造函数需要一个double和一个std::string参数,但你提供了三个值——按照C++14标准,这种参数数量不匹配的列表初始化必须触发编译错误,因为Foo既没有对应参数数量的构造函数,也不属于可以直接聚合初始化的类型(它存在用户自定义的构造函数)。

两款编译器的行为对比

  • g++6.3(符合标准):
    它准确识别了这个错误,给出了清晰的编译提示:

    无法将‘{1, 2, 3}’从‘’转换为‘Foo<std::__cxx11::basic_string >’

  • Visual Studio 15.5.6(不符合标准):
    它错误地跳过了该错误检查,允许代码编译通过,进而导致运行时的未定义行为:b.f.x被赋值为1,但剩余的2和3被错误处理,使得b.f.y变成垃圾值,甚至可能破坏程序内存。

结论

这种行为明显违反了C++14标准中列表初始化的相关规则,属于Visual Studio编译器的bug。好在后续的Visual Studio版本(比如2017的后续更新版本及更高)已经修复了这类列表初始化的检测问题,建议你升级编译器版本来规避这个问题。

内容的提问来源于stack exchange,提问作者AndyMcoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:01:28