Home > Net >  Sizeof applied to parameter of incomplete array type
Sizeof applied to parameter of incomplete array type

Time:03-07

For this code:

int f(int x[])
{
    return sizeof x;
}

GCC produces:

warning: 'sizeof' on array function parameter 'x' will return size of 'int *'

Clang produces:

warning: sizeof on array function parameter will return size of 'int *' instead of 'int[]'

Question: if x has incomplete type (since the size is not present), then is it expected to have:

error: invalid application of 'sizeof' to incomplete type

Extra: does it mean that return size of 'int *' is a GCC/Clang extension?

CodePudding user response:

An array as an argument to a function is actually a pointer. From section 6.7.6.3p7 of the C standard regarding Function Declarators:

A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

This means that this:

int f(int x[])
{
    return sizeof x;
}

Is exactly the same as this:

int f(int *x)
{
    return sizeof x;
}

So x does have complete type and there is no error. Both gcc and clang are being helpful in generating a warning as the result might not be what one expects.

CodePudding user response:

Despite appearances, the x parameter to your f function is not an incomplete type. It is a pointer (int*), because any array, when used as a declared parameter of a function is syntactically equivalent to a pointer to the array's first element.

Thus, the operand of your sizeof x expression is a complete type (pointer to int); the warnings given by the GNU and Clang compilers are merely 'reminding' you of this so-called "decay" of the array to a pointer.

To 'verify' the aforementioned total equivalence, add a forward declaration of the function, using int* x as the formal parameter – there will be (or should be) no further warning about that:

int foo(int* x); // Foward declaration

int foo(int x[]) // Definition - No parameter type conflict
{
    return sizeof x ;
}

CodePudding user response:

Question: if x has incomplete type (since the size is not present), then is it expected to have:

error: invalid application of 'sizeof' to incomplete type

Yes, that would be the usual error message from gcc when one attempts to determine the size of an incomplete type, but that's not what is happening in the example code.

In the parameter list of a function declaration, all parameters declared to have array type -- including incomplete array types -- are adjusted to have corresponding pointer types. This is described in C17 6.7.6.3/7:

A declaration of a parameter as “array of type” shall be adjusted to “qualified pointer to type”, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. [...]

That is a question of the semantics of the source code, not a runtime conversion, though it dovetails with the automatic conversion of array values to pointers that happens at runtime (in principle).

Extra: does it mean that return size of 'int *' is a GCC/Clang extension?

No. The warning message describes the semantics of standard C (since forever).

For what it's worth, I tend to prefer the form in your example when I plan to access the parameter as if it pointed to the first member of an array (by indexing it with [] or performing pointer arithmetic on it). In particular, I always write the two-parameter signature of main as:

int main(int argc, char *argv[]);

CodePudding user response:

When you pass an array into a function, you are actually passing it's address as a pointer. Using sizeof() on the array will only return the size of a pointer. It will not produce an error as sizeof(int*) is a valid operation

  • Related