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; }
It is known that “std” (abbreviation for the standard) is a namespace whose members are used in the program. So the members of the “std” namespace are cout, cin, endl, etc. This namespace is present in the iostream. h header file. Below is the code snippet in C++ showing content written inside iostream.
While this practice is okay for example code, pulling in the entire std namespace into the global namespace is not good as it defeats the purpose of namespaces and can lead to name collisions. This situation is called namespace pollution.
So when we run a program to print something, “using namespace std” says if you find something that is not declared in the current scope go and check std. using namespace std; are used. It is because computer needs to know the code for the cout, cin functionalities and it needs to know which namespace they are defined.
Thus, removing using namespace std; changes the meaning of those unqualified names, rather than just making the code fail to compile. These might be names from your code; or perhaps they are C library functions.
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 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++ 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 namespacestd
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"
andextern "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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With