ANSI-C grammar - array declarations like [*] et alii

后端 未结 3 1140
别跟我提以往
别跟我提以往 2021-02-14 08:54

The ANSI C grammar from -link- give me the following rules for array declarations:

 (1) | direct_declarator \'[\' type_qualifier_list assignment_expression \']\'         


        
3条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-14 09:36

    You can't use type qualifiers or static in size portion of array declaration in C89/90. These features are specific to C99.

    static in array declaration tells the compiler that you promise that the specified number of elements will always be present in the array passed as the actual argument. This might help compilers to generate more efficient code. If you violate your promise in the actual code (i.e. pass a smaller array), the behavior is undefined. For example,

    void foo(int a[static 3]) {
      ...
    }
    
    int main() {
      int a[4], b[2];
      foo(a); /* OK */
      foo(b); /* Undefined behavior */
    }
    

    The * in size portion of array declaration is used in function prototype declarations only. It indicates that the array has variable length (VLA). For example, in the function definition you can use a VLA with a concrete run-time size

    void foo(int n, int a[n]) /* `a` is VLA because `n` is not a constant */
    {
      ...
    }
    

    When you declare the prototype you can do the same

    void foo(int n, int a[n]); /* `a` is VLA because `n` is not a constant */
    

    but if you don't specify the parameter names (which is OK in the prototype), you can't use n as array size of course. Yet, if you still have to tell the compiler that the array is going to be a VLA, you can use the * for that purpose

    void foo(int, int a[*]); /* `a` is VLA because size is `*` */
    

    Note, that the example with a 1D array is not a good one. Even if you omit the * and declare the above function as

    void foo(int, int a[]);
    

    then the code will still work fine, because in function parameter declarations array type is implicitly replaced with pointer type anyway. But once you start using multi-dimensional arrays, the proper use of * becomes important. For example, if the function is defined as

    void bar(int n, int m[n][n]) { /* 2D VLA */
      ...
    }
    

    the the prototype might look as follows

    void bar(int n, int m[n][n]); /* 2D VLA */
    

    or as

    void bar(int, int m[*][*]); /* 2d VLA */
    

    In the latter case the first * can be omitted (because of the array-to-pointer replacement), but not the second *.

提交回复
热议问题