1. 42
  1.  

  2. 7

    They are likely to remove this in the next C standard (or may have already), because a declaration with a static size is “compatible” with a declaration with no static size, and thus you can get unsoundness.

    So your compiler should accept (though the semantics of static suggest this program would be wrong):

    void foo(int a[static 3]);
    void foo(int a[]);
    

    According to the spec, this is fine, but when you come to define the function foo, should it respect the ‘static’ annotation? The spec doesn’t say, and doing static analysis of subsumption for the expressions after ‘static’ is much more complex to keep sound than C prefers in its specification.

    Update: The issue and proposed fix are detailed in N2074, if you’re interested.

    1. 4

      I tend to avoid arrays in parameter declarations like the plague because they are deceiving. Consider:

      static void foo(int arr[10])
      {
              printf("sizeof(arr) = %zu\n", sizeof(arr));
      }
      

      At a glance, it looks like this will print 40 (or more exactly 10 * sizeof(int)). In reality, it’ll print 4 or 8 - whatever sizeof(int *) is equal to. (Yes, I’m assuming ILP32 or LP64.)

      Adding static in there is neat but doesn’t change the dreadful behavior above, so I’ll continue avoiding parameter declaration arrays.

      1. 3

        Very nice! I had no idea of this one.

        void foo(int myArray[10]); The function will still receive a naked int *, but the [10] part can serve as documentation for the people reading the code, saying that the function expects an array of 10 ints.

        Not just for documentation! Sometimes I see people wanting to pass a 2D/3D array to a function, and they use a pointer to pointer, or pointer to pointer to pointer (yeah), when they could simply declare the parameter as a array too! That way, the variable inside the function would be aware of the dimension of each vector component, no ugly arithmetic math needed.

        This is what I do when I assign the pointers to the texts embed in my C project (a 2D array of char *):

        struct game {
            char *texts_embed[LANGUAGE_COUNT][TEXT_NAME_COUNT];
        };
        
        void load_texts_from_data(
        char *texts[LANGUAGE_COUNT][TEXT_NAME_COUNT],
        char *data);
            text[LANGUAGE_ENGLISH][TEXT_NAME_PLAY] = data;
            data = data + STRING_MAX_LENGTH;
            text[LANGUAGE_ENGLISH][TEXT_NAME_OPTIONS] = data;
            data = data + STRING_MAX_LENGTH;
            ...
        }
        
        /* Somewhere else */
        printf("text: %s\n", game->texts_embed[LANGUAGE_ENGLISH][TEXT_NAME_PLAY]);
        
        1. 3

          You will want to be careful that the dimension is retained and it’s not just a pointer.

        2. 3

          Sometimes I get the feeling that C has the habit of using the static keyword in places where is should have been the default behavior.

          1. 1

            care to elaborate? where is static not the default when it should’ve been and why?