为什么获取已声明函数的地址才有效?
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;
这不合法吧?但如果不是,为什么要建设?
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;
我问过 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;
这不合法吧?但如果不是,为什么要建设?
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;