3 ms·
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:
by messe 11mo 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 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.
- bmacho 11mo agoI believe GP meant that the idea of C/C++ should be abandoned, that is, that C and C++ are compatible languages. GP thinks that they should diverge more when necessary, none of them should be held back for the compatibility with the other.
- johnisgood 11mo agoWell, I agree with that.
- 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