考虑以下MCVE:

#include <iostream>

int main()
{
    void foo(int);
    std::cout << foo << std::endl;

    return 0;
}

在这里,我有意尝试以错误的方式打印指向函数的指针,以便选择接受booloperator<< overload
 basic_ostream& operator<<( bool value );

让我感到困惑的是,gcc 7.2clang 5.0都产生警告,但编译并链接了程序。

同时,Visual Studio 15.5.6不会链接此示例。

我个人希望,尽管用作foo的编译器似乎是ODR使用的,但该代码根本不会链接。

谁能解释为什么gcc和clang能够链接程序?

最佳答案

这是违反ODR的行为。但是根据[basic.def.odr]/10,我的重点是:



我们必须回想一下,编译器可以自由地假定您不编写表现出不确定行为或因不需要诊断而格式错误的代码。因为每个函数的地址都必须为非null,所以bool重载只能用true调用,因为这是有效程序中转换必须产生的结果。

我们可以看到GCC 7.3正在这样做。即使是-O0,它也意味着要转换的结果传递1。

关于c++ - 打印函数的地址...声明?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48652424/

10-14 23:32