Skip to content
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

[dcl.array] p.7 may be outdated #4387

Open
RazvanAM opened this issue Nov 23, 2020 · 8 comments
Open

[dcl.array] p.7 may be outdated #4387

RazvanAM opened this issue Nov 23, 2020 · 8 comments
Assignees

Comments

@RazvanAM
Copy link

RazvanAM commented Nov 23, 2020

Paragraph 7 of [dcl.array] (https://eel.is/c++draft/dcl.array#7) states:

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 may also be 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”.

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):

If the type of a parameter includes a type of the form “pointer to array of unknown bound of T” or “reference
to array of unknown bound of T,” the program is ill-formed
. Functions shall not have a return type of
type array or function, although they may have a return type of type pointer or reference to such things.
There shall be no arrays of functions, although there can be arrays of pointers to functions.
Types shall not be defined in return or parameter types. The type of a parameter or the return type for a
function definition shall not be an incomplete class type (possibly cv-qualified) unless the function definition
is nested within the member-specification for that class (including definitions in nested classes defined within
the class).

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?

@jensmaurer
Copy link
Member

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);

@RazvanAM
Copy link
Author

RazvanAM commented Dec 15, 2020

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.

@jensmaurer
Copy link
Member

I'm wondering how much of what we say here is redundant with other places in the standard.

@RazvanAM
Copy link
Author

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.

@RazvanAM
Copy link
Author

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?

@jensmaurer
Copy link
Member

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.

@RazvanAM
Copy link
Author

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 may also be 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".

@jensmaurer
Copy link
Member

Yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants