为什么我的日志在 std 命名空间中?
在下面的代码中,我定义了一个简单的 log
函数.在 main
我尝试 not 来调用它;我调用 std::log
.然而,我自己的 log
被调用了;我看到日志!"在屏幕上.有谁知道为什么?我使用 G++ 4.7 和 clang++ 3.2.
In the code below, I define a trivial log
function. In main
I try not to call it; I call std::log
. Nevertheless, my own log
is called; and I see "log!" on screen. Does anyone know why? I use G++ 4.7 and clang++ 3.2.
#include <iostream>
#include <cmath>
double log(const double x) { std::cout << "log!
"; return x; }
int main(int argc, char *argv[])
{
std::log(3.14);
return 0;
}
推荐答案
C++ Standard 17.6.1.2 第 4 段(强调我的):
C++ Standard 17.6.1.2 paragraph 4 (emphasis mine):
除了第 18 到 30 条和附录 D 中的说明外,每个头 cname
的内容应与相应头 name.h
的内容相同,如在 C 标准库 (1.2) 或 C Unicode TR 中指定,视情况而定,就像通过包含一样.然而,在 C++ 标准库中,声明(在 C 中定义为宏的名称除外)在命名空间 std
的命名空间范围 (3.3.6) 内.未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式 using-declarations (7.3.3) 注入命名空间 std
.
Except as noted in Clauses 18 through 30 and Annex D, the contents of each header
cname
shall be the same as that of the corresponding headername.h
, as specified in the C Standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespacestd
. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespacestd
by explicit using-declarations (7.3.3).
g++ 采用后一种方式,因此一些相同的头文件可以在 C 和 C++ 中重复使用.所以允许g++在全局命名空间中声明和定义double log(double)
.
g++ does it the latter way so that some of the same header files can be reused for C and C++. So g++ is allowed to declare and define double log(double)
in the global namespace.
第 17.6.4.3.3 节第 3 和第 4 段:
Section 17.6.4.3.3 paragraphs 3 and 4:
使用外部链接声明的标准 C 库中的每个名称都保留给实现用作具有 extern "C"
链接的名称,在命名空间 std
和在全局命名空间中.
Each name from the Standard C library declared with external linkage is reserved to the implementation for use as a name with
extern "C"
linkage, both in namespacestd
and in the global namespace.
使用外部链接声明的标准 C 库中的每个函数签名都保留给实现,以用作 extern "C"
和 extern "C++"
链接,或作为全局命名空间中命名空间范围的名称.
Each function signature from the Standard C library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C"
and extern "C++"
linkage, or as a name of namespace scope in the global namespace.
在第 17.6.4.3 节第 2 段的顶部:
And up at the top of Section 17.6.4.3 paragraph 2:
如果程序在保留名称的上下文中声明或定义名称,除非本条款明确允许,否则其行为未定义.
If a program declares or defines a name in a context where it is reserved, other than as explicitly allowed by this Clause, its behavior is undefined.
另一方面,您不得以任何方式声明或定义 ::log
.
You, on the other hand, may not declare or define ::log
in any way.
可惜的是,g++ 工具链没有给你任何错误信息.
It's too bad the g++ toolchain doesn't give you any error messages, though.
相关文章