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

VS2017编译C++虚函数代码异常:是编译器Bug还是未定义行为?

编译器Bug还是未定义行为?

以下C++代码在VS2017中使用cl.exe /GL /O1(全程序优化+优化尺寸)编译时出现异常:

#include <cstdio>

struct Parent {
 virtual const char *name() const { return name2(); }
 virtual const char *name2() const { return "Parent"; }
};

struct Child : public Parent {
 virtual const char *name2() const { return "Child"; }
};

int main() {
 Parent parent{};
 static constexpr Child child{};
 printf("%s\n", child.name());
}
  • 当存在Parent parent{};语句时,程序输出Parent
  • 移除该语句则输出Child

该问题在现代Visual Studio版本及g++中已修复。用户预期输出Child,因为Parent::name应调用Child::name2,现需确认此情况属于编译器Bug还是未定义行为,以及后续能否依赖正常运行结果。


这是VS2017旧版本编译器的Bug,不属于C++标准定义的未定义行为。

从C++标准角度分析:

  • child是Child类型的常量对象,调用name()时,虽然name()是基类Parent的成员函数,但虚函数的动态绑定规则明确要求,必须根据对象的实际类型(Child)调用对应的name2()版本——也就是Child::name2(),所以预期输出Child完全符合标准。
  • 代码中没有任何违反C++标准的写法,Parent parent{};只是一个无关的局部对象声明,不应该影响child对象的虚函数调用逻辑。

VS2017在开启/GL(全程序优化)时出现的错误,是编译器优化阶段的逻辑漏洞,误将child对象的虚函数调用静态绑定到了Parent::name2(),而parent对象的存在触发了这个错误逻辑。现代VS版本和g++无此问题,说明厂商已经修复了该Bug。

后续可以放心依赖正常运行结果,只要使用未存在该Bug的编译器版本即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:19:57