New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lex.name] p3 contradicts to [usrlit.suffix]p1 #5187
Comments
No, that's not the right direction.
No, as you correctly observed, there are additional constraints on the spelling of an identifier. Instead, the combined effect of these rules means that you need to use the "operator user-defined-string-literal" grammar choice for literal-operator-id, because that way you avoid writing a forbidden identifier. (Effectively, you need to write |
The example in over.literal p8 might also be helpful, and directly addresses this case. |
@jensmaurer The concern in this issue is that operator user-defined-string-literal has the form:
Where the ultimate form of the ud-suffix is
The identifier has a cross-reference to [lex.name]. [lex.name] p3.1 sounds like it uniformly applies to all identifiers to which a grammar component will refer. Although, the intent of [lex.name] p3 would say it only applies to these identifiers converted from preprocessing identifier tokens, [lex.name] p3 does not explicitly say such things in the current utterances. This is the obscure point here. Although [over.literal] p8 has a couple of contrast examples double operator""_Bq(long double); // OK, does not use the reserved identifier _Bq ([lex.name])
double operator"" _Bq(long double); // ill-formed, no diagnostic required:
// uses the reserved identifier _Bq ([lex.name]) The comment also refers to [lex.name], but we cannot be aware of the difference when we just purely compare the identifier in an operator string-literal identifier and the identifier in an operator user-defined-string-literal(where the ud-suffix is identifier). |
Also, we can see that [lex.name] make the misunderstanding, https://stackoverflow.com/questions/59180353/is-every-normal-use-of-user-defined-literals-undefined-behavior. Incidentally, [dcl.fct.def#general-8] struct S {
S() : s(__func__) { } // OK
const char* s;
}; Isn't |
To eliminate these obscure points, [lex.name] p3 may be changed to
double operator""_Bq(long double); Although, the ud-suffix has the form of an identifier, however, it's not converted to an identifier token. Instead, in this declaration |
I would say that the introduction of The fundamental problem is that we don't differentiate between lexing (char-by-char) things and higher-level tokens sufficiently clearly. The ud-suffix is a lexing thing; it never forms a preprocessing-token on its own, but is part of a pp-number or similar. It's unfortunate that ud-suffix resolves to identifier; there should be a pp-identifier lexing production instead. Note that we want the underscore prohibition to apply to macro names as well, so we can't defer the checking to phase 7. |
If we prepare to make [lex.name] p3 apply to all phases in [lex.phases], I would say the most identifiers introduced in [cpp] clause would violate [lex.name]. Consider this example # if __has_include(<iostream>)
# include <iostream>
#endif The use of the identifier |
@jensmaurer and it says void operator "" _km(long double); // OK [space — note by me]
float operator ""_e(const char*); // OK [mo space — note by me] So one does not have to write [lex.name]/3 says:
"Use as a name" is a key thing here. Pre-P1787 definition of name says:
Only the whole literal-operator-id |
Good point, but this doesn't change the overall situation. There are two bullets in [lex.name] p3:
Again, the idea is that you're allowed to use _Suffix if you omit the space when writing |
Yep, I was speaking only about the second bullet. For it, with the help of definitions and [over.literal]/8 examples, it is sort of clear that it
(I think the second bullet subsumes the first one) That the first bullet refers to identifier s as preprocessor tokens, can only be gotten from [over.literal]/8 examples: double operator""_Bq(long double); // OK, does not use the reserved identifier _Bq ([lex.name])
double operator"" _Bq(long double); // ill-formed, no diagnostic required:
// uses the reserved identifier _Bq ([lex.name]) which is a suboptimal situation. Another issue is that P1787 removed "that denotes an entity" from the definition of name and it looks like that now any identifier is a name. I have discussed this with @opensdh and IIUC this is on the P1787 issue list. So, I guess, it is up to CWG to decide (and specify?), whether the second bullet only means identifier s which are direct descendants of unqualified-id. |
It is my intent to change [lex.name]/3.2 to avoid "use as a name" entirely rather than to change the definition of name. The concerns about /3.1 and the different phases of translation are their own matter. |
Should have been fixed by #6121. |
[usrlit.suffix]p1 says
That means the identifier in a literal-operator-id at least to have an initial underscore is guaranteed to be valid. However, [lex.name] p3 says
what the form of an identifier stated by the above two bullets can be a valid form in a literal-operator-id, however, as the emphasized wording, [lex.name] p3 explicitly says these identifiers shall not be used otherwise. These two provisions seem to conflict with each other.
Proposal:
change [lex.name] p3 to that
The text was updated successfully, but these errors were encountered: