在没有任何警告或错误的情况下编译以下原因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;
}
背景:我在类中使用了stub函数,以便稍后定义和使用它们。 &#39;后来&#39;永远不会来,我的代码编译和&amp;编译器没有发出关于这些存根的警告或错误。
这是编译器的预期吗?不应该让编译器至少发出警告吗?
答案 0 :(得分:4)
这不是“优化”。 C ++编译器允许您声明任何您希望的内容,前提是声明在语法上有效,并且不引用未定义的类型。这不是特定于成员函数的:非成员函数和全局变量可以在不提供相应定义的情况下声明。
事实证明,编译器和链接器都不能抱怨未完成的声明。即使发出警告也会有问题,因为可能需要单独编译。
编译器不会抱怨,因为它知道另一个cpp文件可能提供定义,并且当链接器运行时,声明就消失了:链接器使用定义和引用,而声明是针对编译器的。
来自评论:
有数百(甚至数千)“没有被应用程序调用”功能 在系统.h文件中。编译器不知道代码所在的位置: 在.cpp源代码中,或在预编译的.obj / .o中,或在.dll / .so中 etc.etc。它是链接器的职责,而不是编译器的职责。所以编译器 默默地忽略了没有“身体”的每一个签名。 - user4419802
答案 1 :(得分:2)
编译器没有优化任何东西,因为首先没有任何东西可以优化。当您声明void T::f();
时,您所做的就是在编译器的内部字典中添加方法签名(如果您愿意)。你永远不会给这个方法一个相应的身体而你从来没有打过它所以它只是“从未发生过”。
答案 2 :(得分:1)
编译器不知道你是否要在另一个编译单元中声明T::f()
,而且它并不关心,因为它'知道'你会得到一个链接器如果你不这样做会出错。