打印功能的地址..声明

Printing the address of function... declaration?

本文关键字:声明 地址 功能 打印      更新时间:2023-10-16

考虑以下mcve:

#include <iostream>
int main() 
{
    void foo(int);
    std::cout << foo << std::endl;
    return 0;
}

在这里,我故意以错误的方式打印指向函数的指针,以使操作员&lt;&lt;选择接受bool的超载。

 basic_ostream& operator<<( bool value );

困扰我的事情是GCC 7.2和Clang 5.0都会产生警告,但编译和链接

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

我个人希望,尽管用作foo的编译器似乎是 odr-使用

有人可以解释为什么 gcc clang 能够链接程序吗?

这是ODR违规。但是根据[BASIC.DEF.ODR]/10,重点是我的:

每个程序应完全包含每个非内线的一个定义 在该程序之外使用ODR的功能或变量 丢弃的声明;无需诊断。定义可以 明确出现在程序中,可以在标准或 用户定义的库,或(在适当的情况下(隐式定义 (请参阅[class.ctor],[class.dtor]和[class.copy](。内联函数 或应在每个翻译单元中定义变量 在废弃的语句之外使用ODR。

,我们必须记住,编译器可以自由地假设您不编写表现出不确定行为的代码,或者以他们不需要诊断的方式不正确。因为每个函数必须具有一个不是null的地址,所以bool过载可以使用true调用,因为这是转换必须在a 有效程序中产生的

我们可以看到GCC 7.3这样做。它通过1通过1的结果,即使在-O0