c++stdintcstdint

<cstdint> vs <stdint.h>


What is the difference between stdint.h and cstdint?

Both of them are available in MSVC (Visual Studio 2010) and gcc-4.5.1. Also both define the intX_t/uintX_t types (where X is the size of the type in bits).

The stdint.h defines each type without any namespace, the cstdint types lies in the std namespace.

cstdint has no file extension and uses the c prefix, stdint.h uses the .h extension.


Solution

  • The original intention in C++98 was that you should use <cstdint> in C++, to avoid polluting the global namespace (well, not <cstdint> in particular, that's only added in C++11, but the <c*> headers in general).

    However, implementations persisted in putting the symbols into the global namespace anyway, and C++11 ratified this practice[*]. So, you basically have three options:

    In practice I suspect that an annoying large amount of code uses the last option, simply because it's easy to do by accident on an implementation where <cstdint> puts the symbols in the global namespace. You should try to use the first. The second has one virtue, that it is guaranteed to put stuff in the global namespace instead of only maybe doing it. I don't think that's particularly useful, but it might save some typing if that's your priority.

    There's a fourth option, #include <cstdint> followed by using namespace std; which is sometimes useful but there are places that you shouldn't put the using namespace std;. Different people will have different ideas where those places are, but "at top level in a header file" is worse than "at top level in a cpp file", which is worse than "in a limited scope". Some people never write using namespace std; at all.

    [*] That means C++ standard headers are permitted to put stuff in the global namespace but not required to. So you have to avoid colliding with those symbols, but you can't actually use them because they might not be there. Basically, the global namespace in C++ is a minefield, try to avoid it. One might argue that the committee has ratified a practice by implementations that is nearly as harmful as sticking using namespace std; at top level in a header file -- the difference being that the implementations only do it for symbols in the C standard library, whereas using namespace std; does it for C++-only symbols too. There's a section in the C standard that lists names reserved for future additions to the standard. It's not a completely stupid idea to treat those names as reserved in the C++ global namespace too, but it's not essential.