It is explained elsewhere on stackoverflow (e.g. here, where unfortunately currently the accepted answer is incorrect---but at least the highest upvoted answer is correct) that the C standard provides that in almost all circumstances an array char my_array[50]
will be implicitly converted to a char *
when it is used, e.g. by passing to a function as do_something(my_array)
, given a declaration of void do_something(char *stuff) {}
. That is, the code
void do_something(char *my_array) {
// Do something
}
void do_something_2(char my_array[50]) {
// Do something
}
int main() {
char my_array[50];
do_something(my_array);
do_something_2(my_array);
return 0;
}
is compiled by gcc without any warnings on any strictness level.
However, paragraph 6.3.2.1.3 of C11 provides that this conversion does not occur specifically if one writes &my_array
, or sizeof(my_array)
(and moreover that these are the only times when this conversion does not occur). The purpose of the latter rule is obvious to me---the sizeof
an array being equal to the size of a pointer to the first element is very confusing, so should be prevented.
But the purpose of the first part of this rule (to do with writing &my_array
) entirely escapes me. See, the rule makes the type of &my_array
(in the notation of the C standard) char (*)[50]
, instead of char *
. When does this behaviour have any use at all? Indeed, except for sizeof
-purposes, why does the type char (*)[50]
exist at all?
For example, it is also explained on stackexchange (e.g. here) that any declared array argument to a function, such as char my_array[50]
in the definition of do_something_2
above, behaves in all ways exactly the same as if char *my_array
was written in the declaration instead, or even char my_array[0]
or char my_array[5]
! Even worse, it means that writing do_something(my_array)
compiles without any type errors in any of these circumstances, while do_something(&my_array)
(i.e. passing an array type of the correct size to a function declared to accept precisely that array type) is an error!
In summary, does the "&
-part" of C11 6.3.2.1.3 have any purpose at all? If so, what is it?
(The only reason I could think of is in order to make sizeof(&my_array)
evaluate to the same thing as sizeof(my_array)
, but this does not even happen due to other C standard rules!---the former sizeof(&my_array)
construction "as expected" indeed reports the size of a pointer, and not the array itself. See here.)