The Linux Kernel Looks To "Bite The Bullet" In Enabling Microsoft C Extensions

submitted by

www.phoronix.com/news/Linux-6.19-Patch-Would-MS…

12
37

Log in to comment

12 Comments

This is hardly newsworthy. If the extensions were called ‘Jabberwocky C Extennsions’ no one would have cared. The extension allows for tagged unnamed structs inside of a struct, e.g.:

struct inner { /* ... */ };
struct outer {
    int value;
    struct inner;
};

Untagged?

You mean ‘unnamed’ is what’s confusing you?

Normally you can do anonymous struct/union members or struct struct/union members that are tagged structs but not anonymous.

I.e. in standard C you’d have to do either:

struct foo { int baz; };
struct bar { struct foo foo; };
...
struct bar data;
data.foo.baz = 0;

or:

struct bar { struct {  int baz; } foo; };
...
struct bar data;
data.baz = 0;

but you can’t do this:

struct foo { int baz; };
struct bar { struct foo; };
...
struct bar data;
data.baz = 0;

Minor correction: Unnamed structs and unions (so your second example) are not part of C. They are GNU extensions.

Unless I’m misunderstanding something, I’m pretty sure they’ve been standardized in C11. Also mentioned here.

You appear to be correct.

Tag is what goes after the struct keyword to allow referring to the struct type. Structs don’t have to have a tag. Name is what field are called. Adapting Obin’s example:

struct foo { int baz; };
struct bar { struct foo qux; };
struct bar data;
data.qux.baz = 0;

foo and bar are tags for struct foo and struct bar types respectively; baz and qux are field names; and data is a variable name.

If I understood correctly, it’s free software anyway, so why the discussion?

Because they wanted drama and clickbaity headline.

This is a non story but people want to hate on MS so will grasp anything they can to try and make a thing out of it.

Comments from other communities

Pedant thought: The thumbnail shows one biting everywhere but the bullet.

it’s time we nibbled the casing and come to terms with bite the bullet, it’s just a bad metaphor.

In Danish and Norwegian the equivalent idiom is to “Swallow a camel” which sounds much funnier xD

Would this cause consequences in terms of the project’s independence? Or are these extensions able to be distributed freely?

From what I can see, the GNU Compiler Collection supports this flag, so you can still build it with 100% free software.

Basically, it’s just behavior that doesn’t align with the C standard, but was introduced by MS. Then, GCC added a compiler flag which makes it behave like that, so that you can build code that requires that behavior.

It doesn’t seem to actually be dependent on MS, rather it’s named after them because it emulates the way their compiler works. I hope no Linux maintainers would entertain the idea of making it dependent on a non-free compiler.

Ah, that makes sense. Thanks for the explanation! :)

behavior that doesn’t align with the C standard

but was introduced by MS

Yep, that tracks. I’m still pissed off about microsoft’s non-standard implementation of HTTP 1.1 from however long ago it was that I had to conditionally work around it on the server side. They believe standards don’t apply to them and it seems like they’re right.

The correct answer. It’s just using an extension Microsoft happens to have made, and everything still works fine without it.

int $ = 3;

Compiled with msvc back in the day for example, could be stuff like that. But IDK.

Why?

I’m sitting around doing IT shit waiting things to download/backup/install/etc and have nothing better to do, so here’s an AI-free explanation with code samples:

It’s basically just a code style thing. Standard C allows you to declare unnamed structs/unions within other structs/unions. They must be unnamed, so it’d look like this:

c struct test { int a; struct { char b; float c; }; double d; };

Which is fine, but the -fms-extensions flag enables you to do the same thing with named structs. For example:

c struct test { int a; struct test2 { char b; float c; }; double d; };

without -fms-extensions, the above will compile, but won’t do what you might assume. b and c will be members of struct test2, not test. So something like this won’t compile:

c struct test my_test; my_test.b = 1; // error: ‘struct test’ has no member named ‘b’

But with the flag, not only does it work, it also lets you do some convenient things like this:

c struct test2 { char b; float c; }; struct test { int a; struct test2; double d; }; //... struct test my_test; my_test.b = 1; //OK

That is, you can reuse an existing struct definition, which gives you a nice little tool to organize your code.

Source: https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html

If this is so convenient, why wasn’t it made a part of a newer C standard?

It’s not that convenient. I can’t even think of a situation where this would be useful for structs, only unions. And in the case of unions, you usually want to keep them as small as possible (or better yet, avoid them altogether).

But besides that, C is a language that tends to prefer minimalism. Using macros, you can accomplish a similar thing already, even if it’s not as nice.

What’s the point of this? If you have a struct within a struct, you probably want them to nest. The -fms-extensions will un-nest them, which is not what you mean.

// If I type this:
struct test {
        int a;
        struct test2 {
                char b;
                float c;
        };
        double d;
};

struct test my_test;

// I want this to happen:
my_test.test2.b = 'x'; //assigning the members of the nested struct
my_test.test2.c = 3.141; //this will work
printf("%f", my_test.c); //this will NOT work since c is a property of test2

You can already do that in standard C like this:

c struct test { int a; struct { char b; float c; } test2; double d; };

I can’t think of any particular reason why you’d want an unnamed struct inside a struct, but you definitely would want to be able to have an unnamed struct inside a union. I suspect the struct-inside-struct thing can become useful in some scenarios involving unions.

Does that really have the same results as the example scenario I described? How would you even access the unnamed struct, since it is unnamed?

The same way you did, via the name of the member: my_test.test2.b = 'x';

The unnamed struct provides the type for a member named test2. Doing it this way saves you the trouble of defining the struct externally and giving it a name. It’s identical to this, except in this example you can reuse the struct definition:

c struct crappyname { char b; float c; }; struct test { int a; struct crappyname test2; double d; };

Once in a while, it turns out that enabling -fms-extensions could allow some slightly prettier code. But every time it has come up, the code that had to be used instead has been deemed “not too awful” and not worth introducing another compiler flag for.

That’s probably true for each individual case, but then it’s somewhat of a chicken/egg situation.

If we just “bite the bullet” as Linus says and enable it once and for all, it is available whenever a use case turns up, and no individual case has to justify it.

A lore.kernel.org search provides these examples:

Undoubtedly, there are more places in the code where this could also be used but where -fms-extensions just didn’t come up in any discussion.

Basically the extensions are useful sometimes. Note that they have nothing to do with Microsoft other than being invented by them.

Old languages should be able to learn new tricks.

Some software require it sadly

The “extend” phase of EEE.

Deleted by author

 reply
6

No? The article literally explains that it’s for something else?

Insert image