为什么获取已声明函数的地址才有效?

Why is Taking the Address of a Function That is Declared Only Working?

我问过 question here about whether taking the address of a function forces the compilation of said function specifically with regard to Substitution-Failure-Is-Not-An-Error. The most direct answer to this can be found here:

Informally, an object is odr-used if its address is taken, or a reference is bound to it, and a function is odr-used if a function call to it is made or its address is taken. If an object or a function is odr-used, its definition must exist somewhere in the program; a violation of that is a link-time error.

但我测试过的所有编译器都表明这是完全可行的:

void foo(int);
auto bar = &foo;

Live Example

这不合法吧?但如果不是,为什么要建设?

来自[basic.def.odr]

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.

foo 是 odr-used,但没有定义(大概 - 否则问题是没有意义的)。该程序格式错误,但由于不需要诊断,因此编译有效。

通常,是链接器发现了定义的缺失,而不是编译器,因为定义很容易出现在不同的翻译单元中。典型的例子是试图将缺少定义的 static const int 传递给对 std::max()std::min() 的调用。

您的示例可以正常工作,因为从未使用过该地址,因此链接器从不搜索该符号。

如果您尝试打印 bar,链接将失败。

void foo(int);
auto bar = &foo;
cout << (void*) bar;

http://ideone.com/97Eo6Z