C++ – User-Defined Literals, Underscores, and Global Names in C++11

c++c++11

In C++11, we get user-defined literals. The C++ standard has examples of these, such as:

long double operator "" _w(long double);

And it says the literal should start with an underscore:

17.6.4.3.5 User-defined literal suffixes
Literal suffix identifiers that do not start with an underscore are reserved for future standardization.

However, there's another section in the standard that says

17.6.4.3.2 Global names
Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

I'm looking to better understand exactly what 17.6.4.3.2 (Global names) says/means and how it relates to 17.6.4.3.5 (User-defined literal suffixes). Specifically:

  • Does the second part of 17.6.4.3.2 (Global names) require user-defined literals (like the above _w) to be defined in a namespace (that is, not in the global namespace)? If so, I wish the standard would've illustrated this.
  • I presume that the first part of 17.6.4.3.2 (Global names) rules out user-defined literals like _W (followed by upper case) and __w and _w__ (two consecutive underscores). Correct?

Edit:

As a follow up, there's a part of the standard that says:

13.5.8 User-defined literals
[…]
2 A declaration whose declarator-id is a literal-operator-id shall be a declaration of a namespace-scope function or function template (it could be a friend function (11.3)), an explicit instantiation or specialization of a function template, or a using-declaration (7.3.3). A function declared with a literal-operator-id is a literal operator. A function template declared with a literal-operator-id is a literal operator template.

Emphasis mine. When it says "namespace-scope" does that mean user-defined literals need to be declared in a user-defined namespace (i.e. not in the global namespace)?

Later edit:

It did not exist when the question was first asked, but now there is also this related question and answer, which readers can additionally check after reviewing the answers below.

Best Answer

What's in a name? 3 Basic concepts [basic] tells us:

4 A name is a use of an identifier (2.11), operator-function-id (13.5), literal-operator-id (13.5.8), conversion-function-id (12.3.2), or template-id (14.2) that denotes an entity or label (6.6.4, 6.1).

which we cross-reference with 13.5.8 User-defined literals [over.literal]:

literal-operator-id:
operator "" identifier

While the name of a literal operator involves an identifier, that identifier does not denote an entity. (Or it's a different identifier and different name that denotes another entity or label altogether.) As such the name of a literal operator never starts with an underscore.

Something like operator""__w is problematic but this is not new: int i__0; is reserved as well.