Aren't a[][] and (*a)[] equivalent as function parameters?

后端 未结 3 389
一向
一向 2021-01-17 15:24

Function prototype

void foo(int n, int a[][]);

gives error about incomplete type while

void foo(int n, int (*a)[]);  
         


        
3条回答
  •  离开以前
    2021-01-17 15:51

    EDIT

    Having read through all the relevant parts of the standard, C11 6.7.6.2 and 6.7.6.3, I believe this is a compiler bug/non-conformance. it apparently boils down to the text that the committee sneaked into the middle of a paragraph concerning array delimiters. 6.7.6.2/1 emphasis mine:

    In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero. The element type shall not be an incomplete or function type. The optional type qualifiers and the keyword static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.

    Now this is of course very poorly written, basically it says

    "peripheral feature of little interest, peripheral feature of little interest, peripheral feature of little interest, OUT OF THE BLUE HERE COMES SOME ARRAY ELEMENT TYPE SPECIFICATION NOT RELATED TO THE REST OF THIS PARAGRAPH, peripheral feature of little interest, peripheral feature of little interest,...."

    So it is easy to misunderstand, fooled me.

    Meaning that int a[][] is always incorrect no matter where it is declared, since an array cannot be an array of incomplete type.

    However, my original answer below raises some valid concerns regarding whether array decay should be done before or after the compiler decides if the type is incomplete or not.


    Given the specific case void foo(int n, int a[][]); only, this is a function declaration. It is not a definition.

    C11 6.7.6.3/12

    If the function declarator is not part of a definition of that function, parameters may have incomplete type

    So first of all, parameters are allowed to have incomplete type in the function declaration. The standard is clear. Which is why code like this compiles just fine:

    struct s; // incomplete type
    void foo(int n, struct s a); // just fine, incomplete type is allowed in the declaration
    

    Furthermore:

    C11 6.7.6.3/4

    After adjustment, the parameters in a parameter type list in a function declarator that is part of a definition of that function shall not have incomplete type.

    After adjustment is very important here.

    Meaning that after adjusting int a[][] to int (*a)[], the parameter shall not have incomplete type. It does not, it is a pointer to incomplete type, which is always allowed and perfectly fine.

    The compiler is not allowed to first evaluate int a[][] as an incomplete array of incomplete arrays, and then later adjust it (if it found that the type was not incomplete). This would directly violate 6.7.6.3/4.

提交回复
热议问题