Why do some includes need the .h and others not? [duplicate]
Why is map imported as #include <map>
, but stdio imported as #include <stdio.h>
?
All standard C++ headers don't want the .h
in the end. I read somewhere that the concept is that they don't need to be actual files, even if I never saw an implementation do it in another manner edit: actually the compiler intrinsics should work considering the headers included but not actually including them as files; see @Yttrill's comment.
For the stdio.h
thing, in a C++ application you shouldn't include <stdio.h>
, but you should instead include <cstdio>
. In general, you shouldn't include the "normal" C headers, but their C++-ized counterparts, which haven't got the .h
in the end, have a c
in front and put all the symbols defined in them in the std
namespace. So, <math.h>
becomes <cmath>
, <stdlib.h>
becomes <cstdlib>
, and so on.
In general, you should use the C++-ized versions of C headers both to avoid to pollute the global namespace (assuming you're not one of those guys who put using namespace std;
everywhere) and to benefit of some C++ improvements to the standard C headers (e.g. added overloading to some math functions).
In general, the implementation of this whole thing is simply done by having such files without extension in the directory in which the compiler looks for the header files. In my g++ 4.4 installation, for example, you have:
matteo@teoubuntu:/usr/include/c++/4.4$ ls
algorithm cstdarg functional sstream
array cstdatomic initializer_list stack
backward cstdbool iomanip stdatomic.h
bits cstddef ios stdexcept
bitset cstdint iosfwd streambuf
c++0x_warning.h cstdio iostream string
cassert cstdlib istream system_error
ccomplex cstring iterator tgmath.h
cctype ctgmath limits thread
cerrno ctime list tr1
cfenv cwchar locale tr1_impl
cfloat cwctype map tuple
chrono cxxabi-forced.h memory typeinfo
cinttypes cxxabi.h mutex type_traits
ciso646 debug new unordered_map
climits deque numeric unordered_set
clocale exception ostream utility
cmath exception_defines.h parallel valarray
complex exception_ptr.h queue vector
complex.h ext random x86_64-linux-gnu
condition_variable fenv.h ratio
csetjmp forward_list regex
csignal fstream set
The C++-ized C headers in theory could just be a
namespace std
{
#include <original_C_header.h>
};
but in general they are more complicated to deal with implementation-specific problems (especially regarding macros) and to add C++-related functionality (see e.g. the previous example of added overloads in <cmath>
).
By the way, the C++ standard (§D.5) do not say that the
<c***>
headers should behave as if they included the <***.h>
headers in a namespace std
directive, but the opposite:
For compatibility with the Standard C library, the C++ Standard library provides the 18 C headers [...] Each C header, whose name has the form name.h, behaves as if each name placed in the Standard library namespace by the corresponding cname header is also placed within the namespace scope of the name-space std and is followed by an explicit using-declaration (7.3.3)
Notice that such headers are considered deprecated (§C.2.1), so this is the main reason you shouldn't use them:
C.2.1 Modifications to headers For compatibility with the Standard C library, the C++ Standard library provides the 18 C headers (D.5), but their use is deprecated in C++.
It's simply the name of the actual file on disk. There is (probably) no file called map.h
or stdio
in your standard include directory.
The C++ standard library moved away from the previous style of using .h
toward not having .h
at the end of the file names. This may possibly have been related to making the syntax look more like templates:
#include<vector>
vector<int> v;
(Preemptive comment: Yes, I know the above needs std::
to build, but it's just an illustration.)
It's just the way it's defined by the C++ Standard -- as it happens, map
and stdio.h
don't even have to be real files.
As a side-note, stdio.h
is the header that was originally imported into C++ from the C standard libraries -- the C++ version is cstdio
. In practical terms, this generally means that when you include cstdio
instead, you get the stuff from stdio.h
, but it's in namespace std.
Just to clarify: the stdio.h
you include in C++ is the C++ version of what was originally a C header. But the C++ way of writing the include is cstdio
.
精彩评论