Repository navigation
CWG2476 [dcl.spec.auto.general] p3 "function declarator" in the rule has a ambiguous meaning #85
Description
Activity
This seems to be squarely what CWG2476 is about, including being precise about "function declarator".
- changed the title
[-][dcl.spec.auto.general] p3 "function declarator" in the rule has a ambiguous meaning[/-][+]CWG2476 [dcl.spec.auto.general] p3 "function declarator" in the rule has a ambiguous meaning[/+]on Jul 7, 2022 This seems to be squarely what CWG2476 is about, including being precise about "function declarator".
The additional notes in CWG2476 says
It was observed that the proposed resolution above does not address the example in the issue
I have updated the proposed wording. We could also add these complex examples for the wording
using type = void(*)(int); void fun(int){} type show(int){ return &fun; } void foo(auto (*ptr)(int)->auto(*)(int)){} auto (*ptr)(int)->auto(*)(int) = &show; foo(&show); // Clang accepts it but GCC rejects
For the last example, I think this is #84.
The proposed wording can be well to explain these complex examples(including the examples mentioned in Additional notes in CWG2476). Could you please merge the proposed wording and the complex examples to CWG2476 or as a new CWG issue that cross-references to CWG2476?
What's the "minimum constituent declaration"? The last three examples in CWG2476 do not seem to be addressed by your suggested changes.
What's the "minimum constituent declaration"?
The smallest declaration the declarator is subsumed to. For example
void fun(int(*ptr)()){}
In this case, the minimal constituent declaration of the declarator
(*ptr)()is the parameter-declaration rather than the function-definition.The last three examples in CWG2476 do not seem to be addressed by your suggested changes.
For
C<auto(*)()->int> c2; // OK, since trailing-return-type specifies the declared return type, which isint, hence there is no more restriction in this case. For the other two cases(C<auto(*)()> c1; // Not OKandC<auto(*)()->auto> c3; // Not OK), they basially has the same reason, the declared return types of these two cases contain placeholder types, hence the proposed bullets apply to these cases. I thought [dcl.name] p1 could be enough to clarify what the minimal declarations for the two casesThis can be done with a type-id, which is syntactically a declaration for a variable or function of that type that omits the name of the entity.
This is based on we have a similar rule, [dcl.decl.general] p3(i.e. the declarators would be analized with the seprated declarations)
Each init-declarator or member-declarator in a declaration is analyzed separately as if it were in a declaration by itself.
By this logical, the minimal declarations of the two case are
auto(*)()andauto(*)()->auto, which are not- paramter-declaration
- initializing declarations of variables
- or, do no declare functions
and the function declarators do not appear in the type-id of a new-expression.
It could arguably say we would consider the minimal declarations are
C<auto(*)()> c1andC<auto(*)()->auto> c3if we don't think [dcl.name] p1 is helpful here. What do you think about?Change the second bullet would be a option
is a initializing declaration of a variable unless the declarator appears in a type-id in a template-argument, or
At the very least, "minimum constituent declaration" isn't the right words, and I do think we need to special-case the template-argument case (because a template argument is not a declaration). The text about type-id is just explanatory and addressing any parsing concerns.
We also need a few examples in the standard text.
In any case, this is squarely in the scope of resolving CWG2476.
In any case, this is squarely in the scope of resolving CWG2476.
Agree that this issue concerns the same things as that of CW2476. Merely, this issue wants to clean two more points
- Clarify the meaning of function declarator
- Try to find wording that can clarify all cases mentioned in CWG2476.
I do think we need to special-case the template-argument case (because a template argument is not a declaration).
From the current situation, I think it is necessary. There seems to not have a concise way to reword and is good enough to clarify these cases.
Full name of submitter (unless configured in github; will be published with the issue): Jim X
A stackoverflow question: Is a pointer to function (sometimes/always?) a function declarator?
[dcl.spec.auto.general] p3 says
Does the function declarator refer to the declarator in a declaration that first matches the form defined in [dcl.fct](namely,
funinT fun();, or to the declarator that is comprised by a declaration that declares a function(namely,T *fun();)? In the latter declaration, the declarator first matches the form defined in [dcl.ptr].Presumably, the wording "function declarator" intends to refer to both.
Suggested resolution
Change [dcl.spec.auto.general] p3 to
The proposed resolution tries to make the intent of the "function declarator" clear and fix the remaining issue in CWG2476.