Open RazvanAM opened 3 years ago
I do not know any cases in which, by the current specification, one cannot use arrays of unknown bound in the type of a function parameter. Are there any such cases that I am overlooking?
What about
template<int> struct C { };
using T = long;
void f(C<sizeof(T[])> x);
What about
template<int> struct C { }; using T = long; void f(C<sizeof(T[])> x);
You are right, all 'contexts' that require a complete type (in this case the operand of sizeof
) must have this requirement satisfied even if they appear in the declaration of a function parameter.
Maybe a better wording for [dcl.array]/7 should be something similar to:
An array bound may be omitted in declarations in which an incomplete object type is allowed. In addition to this, the type of a function parameter can be array of unknown bound of T. [...]
This is because I believe that being in a parameter declaration allows omitting only the array bound of the "top-level declarator" of the parameter (but there is no mention of "top-level declarator" in the standard, nor is the wording completely correct, as it would also allow cases such as void f(int a[ sizeof(int[]) ])
). But I may be mistaken again.
I'm wondering how much of what we say here is redundant with other places in the standard.
After a quick search I did not find anything that allows omitting the array bound in function parameters except for this paragraph. But the first part (arrays of unknown bound are allowed in declarations in which an incomplete object is allowed) can be entailed from the rest of the standard.
I'm wondering how much of what we say here is redundant with other places in the standard.
I apologize, I think I may have misunderstood you at first. Did you mean that removing "in some cases" from [dcl.array]/7 may be enough, because all other contexts that require an array bound even in the declaration of a function parameter are specified explicitly in the standard?
No. I was wondering: What if we removed all this talk about where an array of unknown bounds is permitted in dcl.array p7, and just relied on the fact it's an incomplete type (plus it's effectively complete when we see an initializer). Function parameters may have incomplete type in non-defining function declarations, and the "array of unknown bound" decays to "pointer to X" anyway. Also, [dcl.fct.def.general] p2 prohibits only incomplete class types in function definitions; incomplete array types seem to be fine.
I agree that there is nothing forbidding incomplete types (in general) to be the type of a parameter in a function declaration, except for, as you said, [dcl.fct.def.general]/2, which explicitly prohibits only incomplete class types from being the return type or the type of a parameter in a function definition (implying that other incomplete types, if not explicitly specified otherwise, are allowed), and [basic.def.odr]/12.9, a bullet in a note referring to [dcl.fct.def.general]/2, I believe.
So you are suggesting that [dcl.array]/7 should be changed to:
In addition to declarations in which an incomplete object type is allowed, an array bound may be omitted in some cases in the declaration of a function parameter ([dcl.fct]).An array bound mayalsobe omitted when an object (but not a non-static data member) of array type is initialized and the declarator is followed by an initializer ([dcl.init], [class.mem], [expr.type.conv], [expr.new]). In these cases, the array bound is calculated from the number of initial elements (say, N) supplied ([dcl.init.aggr]), and the type of the array is “array of N U”.
Maybe a note should then be added to either [dcl.array]/7, [dcl.fct.def.general]/2 or [dcl.fct]/5 (or somewhere else, I do not know which place is better suited for this) to specify that a parameter in a function definition is allowed to have the type "array of unknown bound of T".
Yes.
Paragraph 7 of [dcl.array] (https://eel.is/c++draft/dcl.array#7) states:
The wording "an array bound may be omitted in some cases in the declaration of a function parameter", among other changes, was added by the resolution to CWG619.
Actually, the highlighted part ("in some cases") is the only difference between the proposed resolution in February of 2010 and the proposed resolution in March of 2010.
I believe that the only cases in which it was not allowed (at that time) to omit array bounds in the declaration of a function parameter were specified by [dcl.fct] p.8, which stated (in N3035, published in 2010):
However, the highlighted part of [dcl.fct] p.8 (forbidding pointers or references to arrays of unknown bound in the type of a parameter) was removed by the resolution to CWG393.
I do not know any cases in which, by the current specification, one cannot use arrays of unknown bound in the type of a function parameter. Are there any such cases that I am overlooking?