C++ 编译器优化问题

C++ 编译器优化问题,c++,compiler-optimization,C++,Compiler Optimization,编译以下代码会导致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::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;
}
背景:我对类中的函数使用存根声明,目的是以后定义和使用它们。”后来,我的代码被编译了&编译器没有发出关于这些存根的警告或错误


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

编译器不知道您是否要在另一个编译单元中声明t::f,它也不在乎,因为它“知道”如果您不这样做,您将得到一个链接器错误。

编译器不知道您是否要在另一个编译单元中声明t::f,它也不在乎,因为它“知道”如果你不知道,你会得到一个链接器错误。

编译器没有优化任何东西,因为没有任何东西可以优化。当你宣布T::f无效时;如果愿意,您所做的只是将方法签名添加到编译器的内部字典中。您从未给该方法相应的主体,也从未调用过它,因此它只是“从未发生过”。

编译器没有优化任何内容,因为没有任何内容需要优化。当你宣布T::f无效时;如果愿意,您所做的只是将方法签名添加到编译器的内部字典中。您从未给该方法相应的主体,也从未调用它,因此它只是“从未发生过”。

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

事实证明,无论是编译器还是链接器都不适合抱怨未实现的声明。即使发出警告也会有问题,因为可能需要单独汇编

编译器不会抱怨,因为它知道另一个cpp文件可能会提供定义,并且当链接器运行时,声明就消失了:链接器使用定义和引用,而声明是针对编译器的

在评论中:

有数百个甚至数千个应用程序函数没有调用 在system.h文件中。编译器不知道代码所在的位置: 在.cpp源代码中,或在预编译的.obj/.o或.dll/.so中 等等等等。这是链接器的职责,而不是编译器的职责。所以编译器 默默地忽略没有正文的每个签名用户4419802


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

事实证明,无论是编译器还是链接器都不适合抱怨未实现的声明。即使发出警告也会有问题,因为可能需要单独汇编

编译器不会抱怨,因为它知道另一个cpp文件可能会提供定义,并且当链接器运行时,声明就消失了:链接器使用定义和引用,而声明是针对编译器的

在评论中:

有数百个甚至数千个应用程序函数没有调用 在system.h文件中。编译器不知道代码所在的位置: 在.cpp源代码中,或在预编译的.obj/.o或.dll/.so中 等等等等。这是链接器的职责,而不是编译器的职责。所以编译器 默默地忽略没有正文的每个签名用户4419802


编译器不应该发出警告,至少该方法签名字典条目没有任何内容吗?@slashmais在system.h文件中有数百甚至数千个应用程序函数没有调用。编译器不知道代码驻留在哪里:要么在.cpp源代码中,要么在预编译的.obj/.o中,要么在.dll/.so等中。这是链接器的职责,而不是编译器的职责。因此编译器会默默地忽略没有正文的每个签名。@slashmais好吧,dasblinkenlight已经给出了大致相同的说明。在这里进行另一个回答可能会重复。编译器是否应该发出警告,至少该方法签名字典条目没有任何内容?@slashmais system.h文件中有数百甚至数千个应用程序函数未调用。编译器不知道代码驻留在哪里:要么在.cpp源代码中,要么在预编译的.obj/.o中,要么在.dll/.so等中。这是链接器的职责,而不是编译器的职责。因此编译器会默默地忽略没有正文的每个签名。@slashmais好吧,dasblinkenlight已经给出了大致相同的说明。在此处进行另一个回答可能会重复。编译器错误与链接器不同
error.compiler error与linker error不同。当然,linker可以投诉'。它找不到所声明函数的定义:它抱怨。你真的想断言这个程序链接成功吗?没有。@EJP Linker不知道声明了什么,除非它也被使用。这就是OP的程序链接非常好的原因,除非他取消注释T::f的调用。当然,链接器可以抱怨。它找不到所声明函数的定义:它抱怨。你真的想断言这个程序链接成功吗?没有。@EJP Linker不知道声明了什么,除非它也被使用。这就是为什么OP的程序链接非常好,除非他取消注释T::f的调用。