为什么C ++链接器允许未定义的函数? [英] Why does the C++ linker allow undefined functions?
问题描述
这个C ++代码可能令人惊讶地打印出 1
。
This C++ code, perhaps surprisingly, prints out 1
.
#include <iostream>
std::string x();
int main() {
std::cout << "x: " << x << std::endl;
return 0;
}
x
函数原型,这似乎被看作一个函数指针,和C ++标准部分4.12布尔转换说:
x
is a function prototype, which seems to be viewed as a function pointer, and C++ Standard section 4.12 Boolean conversions says:
4.12布尔转换[ bool] 1算术,无范围枚举,指针或指向成员类型的指针可以被
转换为bool类型的prvalue。零值,空指针值,
或空成员指针值转换为false;任何其他值都是
转换为true。对于直接初始化(8.5),
std :: nullptr_t类型的prvalue可以转换为bool类型的prvalue;
的结果值为false。
4.12 Boolean conversions [conv.bool] 1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (8.5), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.
但是, x
从来没有绑定到一个函数。正如我所料,C链接器不允许这样。但是在C ++中这不是一个问题。
However, x
is never bound to a function. As I would expect, the C linker doesn't allow this. However in C++ this isn't a problem at all. Can anyone explain this behavior?
推荐答案
这里发生的是函数指针隐式转换为 bool
。这由 [conv.bool]
指定:
What's happening here is that the function pointer is implicitly converted to bool
. This is specified by [conv.bool]
:
零值零指针值或空成员指针值转换为
false
;
任何其他值转换为true
指针值包括空函数指针。由于从函数名称的衰减获得的函数指针不能为null,因此给出 true
。您可以通过添加<<
where "null pointer value" includes null function pointers. Since the function pointer obtained from decay of a function name cannot be null, this gives true
. You can see this by including << std::boolalpha
in the output command.
以下操作会导致g ++中的链接错误:(int) x;
The following does cause a link error in g++: (int)x;
关于此行为是否允许,C ++ 14 [basic.odr.ref] / 3
说:
Regarding whether this behaviour is permitted or not, C++14 [basic.odr.ref]/3
says:
一个名称显示为...]
A function whose name appears as a potentially-evaluated expression is odr-used if it is the unique lookup result or the selected member of a set of overloaded functions [...]
如果
是唯一的查找结果或一组重载函数的选定成员, b
这覆盖了这种情况,因为输出表达式中的 x
被查找到 x
,这是唯一的结果。然后在 / 4
中我们有:
which does cover this case, since x
in the output expression is looked up to the declaration of x
above and that is the unique result. Then in /4
we have:
每个程序都应包含一个在该程序中使用的每个非内联函数或变量;无需诊断。
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
所以程序是错误的,但不需要诊断,这意味着程序的行为是完全未定义的。
so the program is ill-formed but no diagnostic is required, meaning that the program's behaviour is completely undefined.
此子句意味着 x();
不需要链接错误,执行角度;这将是愚蠢的。 g ++
在这里选择的课程对我来说似乎是合理的。
Incidentally this clause implies that no link error is required for x();
either, however from a quality-of-implementation angle; that would be silly. The course that g++
has chosen here seems reasonable to me.
这篇关于为什么C ++链接器允许未定义的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!