5 ms·
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
by unwind 11mo 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#index-fms-extensions https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#in...
- messe 11mo agoThe 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 https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html
- creshal 11mo agoWhy is this still not standardized?
- wahern 11mo agoThe original proposal at https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1406.pdf 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++.
- avadodin 11mo agoIf C and C++ standardization had included both languages since the beginning, compatibility could have been a thing but it didn't so the languages have diverged since C-with-classes. I don't understand why the C standard has to get bogged down with bizarro-world-C restrictions from C++. It's 2025, people have to give up on C/C++.
- IsTom 11mo agoC++ routinely includes C headers and this would affect that. I think most things valid in C, but not C++ don't affect declarations.
- johnisgood 11mo ago> It's 2025, people have to give up on C/C++. No, people should not give up on C. ??? You do realize there are a lot of projects written in C, right? Including Linux and most of its programs / utilities that you may be using. I have new projects written in C, too, and you can do a lot to check for potential bugs using various flags to GCC / Clang, among other things like cppcheck and the rest. No, people should not give up on C. C is really good to know, for many reasons... even if you are not going to use it.
- stefantalpalaru 11mo ago[dead]
- RobotToaster 11mo agoAm I right to think this is really unobjectionable, and is only being objected to because MS "invented" it?
- zinekeller 11mo agoborder-box says hi [1] [1]: https://www.paulirish.com/2012/box-sizing-border-box-ftw/ https://www.paulirish.com/2012/box-sizing-border-box-ftw/ (Funnily, tables always default to border-box, so the objections in CSS standardization at the time is really silly.)
- plorkyeran 11mo agoEven if it was some other vendor the fact that it's non-standard isn't great.
- jeroenhd 11mo agoThe "vendor" in this case is GCC and there are plenty of non-standard GCC extensions in use today. The Linux kernel standard gnu89, not C89, after all. I doubt you can even compile a usable Linux kernel sticking purely to the official C standard. The same tricks are also enabled in the plan9 extensions, but enabling plan9 extensions also enables a bunch of other tricks and those changes landed later than the Microsoft ones. Aiming to enable plan9 instead probably could've saved the Linux kernel half a decade of "Microsoft bad" comments, though.
- messe 11mo agoI think it's been gnu11 for a few years now.
- jeroenhd 11mo agoAh, you're right, I guess I must've been directed to an outdated documentation site when I looked up the exact configuration Linux uses. Still, it's not the official C standard, but a specific flavour of C11, so my point still stands.
- qalmakka 11mo agostruct parent *p = (struct child *)c; // valid Note that this cast would be valid without the MS extensions too, you can always cast a pointer to a struct to a pointer to its first member and viceversa. What the MS extensions allow you to do is to just do `c->i` directly, without having to name the parent
- arguflow 11mo agoA 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.de/ https://lore.kernel.org/lkml/200706301813.58435.agruen@suse....