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.