10 comments

  • fuhsnn an hour ago

    > though some may feel the wrong way around Microsoft C behavior being permitted

    The same extension can be enabled with `-fplan9-extensions`, might be more appealing to some!

    • tleb_ 15 minutes ago

      -fplan9-extensions adds even more, it is not an alias: https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Unnamed-Fields...

      One of the link of past discussions was from Apr 2018 and discusses it. At that time GCC -fplan9-extensions support was too recent (gcc-4.6) to be considered. https://lore.kernel.org/lkml/20180419152817.GD25406@bombadil...

      Now the reasoning isn't present in the patch but it probably is because they want step increments and -fms-extensions is a small-ish first step. Maybe -fplan9-extensions could make sense later, in a few years.

    • Quarrel 8 minutes ago

      It certainly seems to me that using this would eliminate 75% or so of the objections to it.

      For this use case, at least, it feels like a CS version of racism. MSFT is bad, so no MSFT.

      It largely clears up an idiosyncrasy from the evolution of C.

      (but, as someone that briefly worked on plan9 in 1995/96, I like your idea :)

  • unwind 2 hours ago

    Huh. I thought the article was vague on what exactly these extensions permit, so I'd thought I'd look up the GNU documentation. Surprisingly, it [1] was rather vague too!

    The only concrete example is:

    Accept some non-standard constructs used in Microsoft header files.

    In C++ code, this allows member names in structures to be similar to previous types declarations.

        typedef int UOW;
        struct ABC {
          UOW UOW;
        };
    
    
    [1]: https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#in...
    • messe 2 hours ago

      The important one is "Unnamed Structure and Union Fields"[1], in particular unnamed structs and union fields without a tag.

      ISO C11 and onward allows for this:

          struct {
            int a;
            union {
              int b;
              float c;
            };
            int d;
          } foo;
      
      In the above, you can access b as foo.b. In ISO C11, the inner struct/union must be defined without a tag. Meaning that this is invalid:

          struct {
            int a;
            union bar {
              int b;
              float c;
            };
            int d;
          } foo;
      
      As is this: union bar { int b; float c; };

          struct {
            int a;
            union bar;
            int d;
          } foo;
      
      -fms-extensions makes both of the above valid. You might be wondering why this is uesful. The most common use is for nicer struct embedding/pseudo-inheritance:

          struct parent {
            int i;
            void *p;
          };
      
          void parent_do_something(struct parent *p);
      
          struct child {
            struct parent;
            const char *s;
          };
      
          struct child *c;
          struct parent *p = (struct child *)c; // valid
          parent_do_something(p);
          c.i++; // valid
      
      [1]: https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html
      • creshal an hour ago

        Why is this still not standardized?

        • wahern 18 minutes ago

          The original proposal at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1406.pdf explains why.

          > Some implementations have permitted anonymous member-structures and -unions in extended C to contain tags, which allows tricks such as the following.

            struct point { float x, y, z; };
            struct location {
              char *name;
              struct point; // inheritance in extended C, but
                            // forward declaration in C++
            };
          
          > This proposal does not support that practice, for two reasons. First, it introduces a gratuitous difference between C and C++, since C++ implementations must treat the declaration of point within location as a forward reference to the type location::point rather than a definition of an unnamed member. Second, this feature does not seem to be used widely in applications, perhaps because it compiles differently in extended C vs. C++.

          See https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1406.pdf

    • arguflow 2 hours ago

      A really good example of it is in this lore thread here [1]. He explains it better than me so I'll just link it here

      [1]: https://lore.kernel.org/lkml/200706301813.58435.agruen@suse....

  • mrlonglong an hour ago

    Microsoft "embrace, extend and takeover" comes to mind here. Caveat emptor.

    • pezgrande 21 minutes ago

      Isn't this a case of Evil Linux embracing M$ in order to extinguish it?