Legacy standard C library headers and overloaded C++ functions
C++ language standard says in D.5
2 Every C header, each of which has a name of the form name.h
, behaves as if each name placed in the standard library namespace by the corresponding cname
header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std
and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
3 [ Example: The header <cstdlib>
assuredly provides its declarations and definitions within the namespace std
. It may also provide these names within the global namespace. The header <stdlib.h>
assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std
. —end example ]
This seems to state rather explicitly ("... each name ...", "...the same declarations...") that the old-style <name.h>
headers must provide the same set of declarations as the new-style <cname>
headers, but in global namespace. No exception is made for C++-specific overloaded versions of various C functions, for one example.
That appears to mean that <math.h>
must provide three versions of sin
function: sin(float)
, sin(double)
and sin(long double)
in global namespace. This, in turn, means that the following C++ code should fail overload resolution
#include <math.h>
int main() {
sin(1);
}
It does fail under MSVC++ compiler, but it compiles successfully under GCC and Clang. So, does GCC just ignore the standard requirement with regard to deprecated old-style headers? Or do I somehow misinterpret the wording in the standard?
Thanks to @hvd's comments I have seen the light, it turns out MSVC is correct and GCC should be complaining about the ambiguity as well.
The only differences between including <cmath>
vs <math.h>
are where the names are originally scoped, which is in namespace std
for the former, and the global namespace for the latter (implementations are free to provide the names in the other namespace as well, but this isn't mandated), and the fact that including the .h
variants of C headers is deprecated.
上一篇: 命名空间问题:向前声明和混合命名空间
下一篇: 传统的标准C库标题和重载的C ++函数