编译优化问题

Compiler optimization issue

编译以下导致 T::f() 在没有任何警告或错误的情况下被优化:

#include <iostream>

struct T
{
    int t;
    void f(); //undefined..
};

int main()
{
    T t;
    t.t = 1;
    //t.f(); //<-- compiler-error only when used, otherwise optimized-out
    std::cout << t.t;
    return 0;
}

背景:我在 class 中对函数使用存根声明,目的是稍后定义和使用它们。 'Later' 从来没有出现过,我的代码已编译并且编译器没有发出关于这些存根的警告或错误。

这是编译器所期望的吗?;编译器不应该至少发出警告吗?

编译器不知道你是否要在另一个编译单元中声明T::f(),它不关心,因为它'knows'你会得到一个linker 错误,如果你不这样做。

编译器没有优化任何东西,因为一开始就没有什么可以优化的。当您声明 void T::f(); 时,您所做的只是向编译器的内部字典添加一个方法签名,如果您愿意的话。你从来没有给这个方法一个相应的主体,你从来没有调用它所以它只是 'never happened'.

这不是 "optimization"。 C++ 编译器允许您声明任何您想要的东西,前提是该声明在语法上是有效的,并且不引用未定义的类型。这不是特定于成员函数:非成员函数和全局变量可以在不提供相应定义的情况下声明。

事实证明,编译器和链接器都不适合抱怨未完成的声明。由于单独编译的可能性,即使发出警告也会有问题。

编译器不会抱怨,因为它知道另一个 cpp 文件可能会提供定义,并且当链接器运行时,声明已经消失:链接器处理定义和引用,而声明用于编译器。

来自评论:

There are hundreds (or even thousands) "not called by app" functions in system .h files. The compiler doesn't know where the code resides: either in your .cpp source, or in precompiled .obj/.o, or in .dll/.so etc.etc. It's linker's duty, not the compiler's one. So the compiler silently ignores every signature without "body". – user4419802