CLANG 5.0.0 涉及虚函数的 coliru/godbolt 差异
clang 5.0.0 difference on coliru/godbolt involving virtual function
我真的希望我错过了一些东西,但请考虑以下代码:
struct Base {
virtual void doit() = 0;
};
struct Derived : Base {
void doit_internal(int n);
void doit() {
doit_internal(3);
}
};
int main() {
Derived derived;
}
在 clang (5.0.0-3~16.04.1 (tags/RELEASE_500/final)
( 上,我收到链接器错误 (undefined reference to Derived::doit_internal(int)'
(。我想知道如果实际上根本没有调用doit_internal
,为什么需要它。
此外,在 clang (version 5.0.0 (tags/RELEASE_500/final 334239)
(,它可以很好地编译。
哪个叮当声是正确的?标准中是否有技术原因/平台特定的东西/某些东西要求doit_internal
定义?
程序格式不正确,无需诊断。在定义doit
时,你使用了 odrdoit_internal
(你写了一个调用doit_internal
的表达式(。您的程序可以优化到return 0;
没有区别
该标准明确指出:
[basic.def.odr]
4 每个程序应只包含一个定义 该程序中使用的非内联函数或变量 在丢弃的语句之外;无需诊断。这 定义可以显式出现在程序中,可以在 标准或用户定义的库,或者(在适当时(它是 隐式定义(参见 [class.ctor]、[class.dtor] 和 [class.copy](。 每次翻译中都应定义内联函数或变量 在丢弃语句之外使用 ODR 的单位。
Clang完全有权拒绝它,或者不拒绝它。它甚至可以在版本之间更改其行为,因为您的程序违反了上述要求。
在这两种情况下,程序都可以正确编译。
但是coliru
它在链接过程中失败,因为没有定义Derived::doit_internal(int)
。
Compiler Explorer
不运行代码,它只显示为当前翻译单元定义的C++代码的汇编代码。所以它不必做链接。由于未执行链接阶段,因此不会发现问题,也不会报告错误。
doit_internal
是必需的,因为您的一个函数引用了它。虽然该函数本身未被引用,但它是应用程序的基础部分,因此链接器需要其依赖项。
如果启用优化,则 clang 会省略doit
的实现,并且您的应用程序链接成功:http://coliru.stacked-crooked.com/a/8496f4e097d2f0ee
Godbolt只是一个编译器,它不链接或运行任何东西,这就是为什么它没有显示任何链接错误。请注意,它在程序集中仍然有call Derived::doit_internal(int)
,因此如果您采用此程序集并尝试链接它,则最终会出现相同的链接器错误。
- CLANG 5.0.0 涉及虚函数的 coliru/godbolt 差异
- 编译器资源管理器(godbolt)如何安全地运行代码?
- 如何在 godbolt.org 启用地址清理器
- 为什么 Coliru 的 Clang 无法编译 vector::p ush_back?
- Godbolt 在 MSVC 上包含 Windows.h 时无法链接?
- 如何在 godbolt 上使用 Google Benchmark
- 为什么godbolt生成的asm输出与我在Visual Studio中的实际asm代码不同
- 下面显示的代码片段在 Coliru 和 Ideone 中编译,但根据 iso § 8.5 p6,它不应该,还是我错过了什么?
- 为什么这段代码在 Coliru 上编译,而不是在 Xcode 上编译
- clang 在 Coliru 中编译此代码段,但不在编译器资源管理器中编译.为什么
- 为什么coliru对chrono::system_clock::now().time_since_epoch()返回相同