Why is my log in the std namespace?
c++, namespaces, overloading
Solution
C++ Standard 17.6.1.2 paragraph 4 (emphasis mine):
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 header `name.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 namespace `std`. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace `std` by explicit using-declarations (7.3.3).
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.
Section 17.6.4.3.3 paragraphs 3 and 4:
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 namespace `std` and in the global namespace.
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.
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.
You, on the other hand, may not declare or define `::log` in any way.
It's too bad the g++ toolchain doesn't give you any error messages, though.
Problem
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!\n"; return x; } int main(int argc, char *argv[]) { std::log(3.14); return 0; } ```