1

At [over.literal] I read, in the list of examples, that

double operator""_Bq(long double);

is valid, whereas

double operator"" _Bq(long double);

is ill-formed, which is apparently a consequence of the space right after "".

Now, from the linked page, I can easily get to [usrlit.suffix] with one click and I read that

Literal suffix identifiers that do not start with an underscore are reserved for future standardization.

Good, but where do I read why operator"" _Bq is invalid?

I've also read the description of user-defined-string-literal on cppreference, but to be honest I've found it a bit confusing.

Can anybody break that down with examples?

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 7
    The comment next to the second example says why it's not allowed - `_Bq` is a reserved name per http://eel.is/c++draft/lex.name#3.1 (`_` followed by uppercase letter). Note that the example `_km` is fine. – cigien Feb 06 '23 at 09:58
  • 1
    It says "ill-formed NDR", not just "ill-formed". – HolyBlackCat Feb 06 '23 at 09:59
  • @cigien, ok, but how does that change the way I can make use of it? As in, if `_Bq` is reserved, won't it be always wrong to write, say, `12.34_Bq`? Why adding a space in the declaration of `operator""_Bq` changes this? – Enlico Feb 06 '23 at 10:07
  • @Enlico : The way you use the operator doesn't change, only the way it's declared – ildjarn Feb 06 '23 at 10:12
  • 7
    Adding a space opens it up for macro expansion. `operator""_Bq` is [one pptoken](http://eel.is/c++draft/lex.pptoken), whereas `operator"" _Bq` is two pptokens, and the second one can be expanded if an implementation defines a macro with (reserved) name that is `_Bq`. – StoryTeller - Unslander Monica Feb 06 '23 at 10:14
  • @StoryTeller-UnslanderMonica, does that mean that, in the future, the standard might for instance make use of `double operatror"" _Bq(long double)` for something which will anyway _not_ map to the use of a literal like `12.34_Bq`, because this will always call `double operatror""_Bq(long double)` instead? – Enlico Feb 06 '23 at 10:16
  • @StoryTeller-UnslanderMonica _`operator""_Bq` is one pptoken, whereas `operator"" _Bq` is two pptokens_ `operator""_Bq` is two pptokens, `operator"" _Bq` is three – Language Lawyer Feb 06 '23 at 10:17
  • @LanguageLawyer - user-defined-string-literal is a single grammatical element under valid preprocessing-tokens. It's one. – StoryTeller - Unslander Monica Feb 06 '23 at 10:19
  • @StoryTeller-UnslanderMonica `operator""_Bq` is not an user-defined-string-literal, only `""_Bq` is – Language Lawyer Feb 06 '23 at 10:20
  • 1
    Anyway, if one follows the grammar productions and tries not to be intentionally obtuse, there is a plug in that hole @Enlico. The space breaks it up for preprocessing. It's not about the standard using `operator"" _Bq`, it's about `_Bq` being it's own "thing" lexically. – StoryTeller - Unslander Monica Feb 06 '23 at 10:23
  • 3
    Instead of `operator"" _Bq` try `operator"" _DEBUG` and see what happens. – BoP Feb 06 '23 at 10:42
  • 1
    `""_Bq` is different from `"" _Bq` for the same reason that `double` is different from `dou ble`. – Eljay Feb 06 '23 at 13:56

1 Answers1

7

"" _Bq is a string-literal followed by an identifier, whereas ""_Bq is a user-defined-string-literal which is a single, distinct preprocessing token ([lex.pptoken]).

As a consequence, the former is affected by macro expansion, but the latter is not:

#define _x
int operator "" _x(char); // becomes `int operator "" (char);` which is invalid
int operator ""_x(char);  // ok

That aside, both forms are allowed as part of a literal-operator-id and have the same meaning. However, since forming the first construct involves the use of a reserved identifier, it is ill-formed with no diagnostic required per [lex.name]/3 (motivation for this being that _Bq could be in use by the implementation as a macro).


That's the intent, anyway. The current normative wording does not actually make that difference clear enough: user-defined-string-literal ultimately contains an identifier, and [lex.name]/3 has no indication that it only applies to identifiers that are themselves preprocessing tokens. This is the subject of CWG2521.

duck
  • 1,455
  • 2
  • 8