https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114873

--- Comment #5 from Halalaluyafail3 <luigighiron at gmail dot com> ---
(In reply to Joseph S. Myers from comment #4)
> These are not meant to be valid C (although the relevant requirement isn't a
> Constraint, so a diagnostic isn't required); see the discussion in DR#341.

I thought these declarations were supposed to be valid since there doesn't seem
to be anything forbidding them (unless I misunderstood the text "part of the
nested sequence of declarators or abstract declarators for a parameter
declaration") and they seemed to make sense to me. I did see DR#341 before
making this bug report, and I assumed that it was specifically referring to the
case of [*] in array sizes. Thanks for making the intent clear.

I have recently thought about this again and realized that there may be an
alternative way of doing this:

void foo(typeof(int(*)[(0,0)])(*)[*]);
void bar(_Atomic(int(*)[(0,0)])(*)[*]);

It looks correct as (0,0) is not an integer constant expression and the array
type isn't [*]. GCC and Clang seem to accept this without complaint as well
(haven't tested other compilers). However the current wording says:

> If the size is an expression that is not an integer constant expression:
> if it occurs in a declaration at function prototype scope, it is treated
> as if it were replaced by *; otherwise, each time it is evaluated it shall
> have a value greater than zero.
Section 6.7.7.3 "Array declarators" Paragraph 5 N3220

This wording seems to say that the expression (0,0) would be replaced by *
which would make the program invalid? Or perhaps it means that the type gets
adjusted in the parameter declaration itself so that this is valid. The wording
doesn't seem very clear here, though if it was the former approach then the
following declarations would be invalid:

//the type names in typeof and sizeof have function prototype scope
void baz(size_t x,typeof(int[x])*y);
void qux(size_t x,int(*y)[sizeof(char[x])]);

Which seems unintended. I think this text should be updated to state how *
replacement happens in cases like these. It also isn't clear what would happen
in a declaration like the following:

int a=1;
typedef int b[a];//VLA outside of function prototype scope
void(*c)(b*);//then used in function prototype scope

This would depend upon whether 'it' refers to where the size expression is, or
to where the type is used and then gets adjusted.

Reply via email to