为什么C ++链接器允许未定义的函数? [英] Why does the C++ linker allow undefined functions?

查看:209
本文介绍了为什么C ++链接器允许未定义的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆