Why do some includes need the .h and others not? [duplicate]

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++.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)