17

In C++11 I can choose whether I want to use the types defined in with or without the namespace std::

At least my compiler (g++ 4.7) accepts both variants.

My question is: What is the recommended way to use the typedefs from cstdint. With or without the namespace? What are the advantages or disadvantages? Or is it only a matter of style?

so variant a):

#include <cstdint>
std::uint8_t n = 21;

resp:

#include <cstdint>
using std::uint8_t;
uint8_t n = 21;

or variant b):

#include <cstdint>
uint8_t n = 21;
3
  • I think C++11 removed the restruction of the C stuff being in std. Commented Oct 29, 2012 at 21:29
  • 1
    I think you meant "std::" in your first example, not "std:" Commented Oct 29, 2012 at 21:31
  • I would use #include <stdint.h> uint8_t n = 21;. Commented Oct 30, 2012 at 17:34

5 Answers 5

16

Prefer names declared in the std namespace. The reason is given in §17.6.1.3/4 (ISO/IEC 14882:2011(E), C++11):

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 header name.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 namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

If you use the names from the <cname> headers without std, your program is relying on unspecified requirements.

This was different in C++03 and earlier where names were only supposed to appear in the std namespace. However, the reality was that many implementations were simply injecting the contents of the C standard library headers <name.h> into std and so this was accommodated for in C++11. The corresponding section (§17.4.1.2/4) from the C++03 standard says:

Except as noted in clauses 18 through 27, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause 7), or ISO/IEC:1990 Programming Languages—C AMENDMENT 1: C Integrity, (Clause 7), as appropriate, as if by inclusion. In the C++ Standard Library, however, the declarations and definitions (except for names which are defined as macros in C) are within namespace scope (3.3.5) of the namespace std.

Further to this, qualifying names with std:: helps to avoid collisions - you know exactly what you're getting if you fully qualify it. If you're really going to do using namespace std or using std::something, at least do it in as minimal a scope as you can.

Sign up to request clarification or add additional context in comments.

Comments

8

In C++11, for the C headers that are explicitly named in the C++ standard, the following holds:

  • An implementation is required for the <foo.h> versions to add them in the global namespace, and allowed to add them to the std:: namespace.

  • An implementation is required for the <cfoo> versions to add them in the std:: namespace, and allowed to add them to the global namespace.

Comments

4

The reason for wrapping things in the std namespace in the <cstdint> header is to avoid name collisions, which are quite unpleasant when they happen. However, in this case, it is very unlikely that the types will be found somewhere else. So I would use <stdint.h>, especially because this feature was introduced in C before it was added to C++, and hence the <stdint.h> header is older than <cstdint>, and therefore available in older compilers.

If you have decided that you want these names in the global namespace, you should also prefer <stdint.h> to <cstdint> followed by using namespace std, as the latter will dump all the other std stuff from other <cfoo> headers yhou have included into the global namspace too, which you probably do not want, as many other standard names are much more collision-prone than the likes of uint8_t.

Comments

2

Include <cstdint> and use std:: or include <stdint.h> to use unqualified type names. There are some platforms (e.g. QNX SDP 6.6) on which <cstdint> doesn't declare those types in the global namespace.

Comments

1

My personal style is to always fully qualify names so it is clear where they come from. That is, I would use std::uint8_t. That is, I would include <cstdint> and use qualified names.

That said, note that use of std::uint8_t is only indicated if you really mean to use a type with exactly 8 bits. If the platform you are running your code on doesn't have such a type, e.g., because it uses 9 bit units as its basic entity, the program is supposed not to compile. If you want to use the smallest unsigned with 8 bits available, you want to use uint_least8_t.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.