On 10/06/2025 10:17, LIU Hao wrote:
在 2025-6-10 15:52, David Brown via Gcc 写道:
On 09/06/2025 12:13, Andreas Schwab wrote:
On Jun 09 2025, Chris Bazley via Gcc wrote:

C is a language that allows considerable latitude in where things are placed:

     static int volatile p;
     volatile int static q;

C23 says (6.11.5 Storage-class specifiers):

     The placement of a storage-class specifier other than at the
     beginning of the declaration specifiers in a declaration is an
     obsolescent feature.


...


The latitude that C allows for ordering in declarations comes from two main sources.  Sometimes it is because it was thought that it made the syntax and grammar rules of the language simpler.  But mostly it was because the original C standard was formed from existing practice - existing inconsistent C compilers, and existing inconsistent C source code.  It allowed "static int volatile" and "volatile int static" because enforcing an order - /any/ order - would make significant existing C code incorrect with the new standard.  It was not done for good language design - it was done despite it being a bad feature for the language.


May I ask what you would think about this

    ```
    static const struct Foo
      {
        int first;
        int second;
      }
    foo_table[] =
      {
        { 1, 2 },
        { 3, 4 },
        { 5, 6 },
      };
    ```

versus this?

    ```
    struct Foo
      {
        int first;
        int second;
      }
    static const foo_table[] =   // alt. `constexpr foo_table[] =`
      {
        { 1, 2 },
        { 3, 4 },
        { 5, 6 },
      };
    ```

Personally, I don't like either of these! My general preference is to declare one thing at a time. So if I want a named struct type "struct Foo", I'd use :

        struct Foo { int first; int second; };

        static const struct Foo foo_table[] = {
                ...
        };

If I wanted the struct type to be unnamed and only used once, I'd write:

        static const struct { int first; int second; } foo_table [] = {
                ..
        };

That follows the normal (for me) pattern of <storage-class specifier> <type qualifiers> <type specifier> <declarator = initializer>.


Of course I appreciate that different people have different preferences for this kind of thing. However, I am far from convinced that that is a good thing in the language. There are situations where it is good for a language to be flexible and allow multiple ways to write the same thing. But that can also be a disadvantage - if some people are writing "static" in the middle of their declarations, some people at the start, and some people near the end, then code gets inconsistent and mistakes are made when reading or maintaining code. Flexibility like this has its pros and cons. Perhaps flexibility in the #embed parameter order is more important than consistency - but that should be decided by arguing that the flexibility is important, not by saying that C lacks order in other aspects.


David

Reply via email to