Live data from Hacker News

Learning that you can use unions in C for grouping things into namespaces

utcc.utoronto.ca

61–70 of 150 posts

Re: Learning that you can use unions in C for grouping things into namespaces

#61
post #18

Earlier quoted context omitted.

One of the very few things from C that I miss in C++ is anonymous structs and enums. I really don’t understand why they are not allowed. That is, C style enums don’t have to have a name but “type safe” (enum class) ones do. One classic use is to name an otherwise boolean option in a function signature; there’s typically no need to otherwise name it. C++ incompatibly requires a name for all struct and class declaratio…

> I really don’t understand why they are not allowed. I don't, either. Such were in D from 2000 or so. I also don't understand why `class` in C++ sits in the tag name space. I wrote Bjarne in the 1980s asking him to remove it from the tag name space, as the tag name space is an abomination. He replied that there was too much water under that bridge. D doesn't have the tag name space, and in 20 years not a single pers…

The only explanation I saw was that C++ standards guys were horrified by the idea of unpredictable side effects as a result of initialization of a struct.

I think C++ though is adding them.

What I'd like in c is designated function parameters.

  // these the same
  bar(.a = 10, .b = 12);
  bar(.b = 12, .a = 10);

Re: Learning that you can use unions in C for grouping things into namespaces

#62

Earlier quoted context omitted.

I don't see any undefined behavior here. As I mentioned below, gcc explicitly documents type punning via unions as being well defined. But yes, this is compiler specific and is not guaranteed to work elsewhere.

Accessing packed struct members works fine on x86, but will blow up at runtime or do weird things on platforms which don't support unaligned loads or stores. The correct way to access packed structs is through memcpy, just like you'd access any other potentially unaligned object.

For architectures where unaligned accesses are illegal, gcc will generate multiple load/store instructions when accessing packed struct fields by name. The main caveat to look out for is taking the address of a packed struct member and then dereferencing it.

Re: Learning that you can use unions in C for grouping things into namespaces

#63

Bleurgh. I have a deep soft spot for C, and I'm known to get twisted pleasure from using obscure language features in new ways to annoy people, but this is a level of abuse that even I can't get behind. If you need namespacing, use C++. As much as I love C, it's terrible for large projects.

Linux kernel is large project and clearly C is sufficient for it, given the fact that migrating to C++ would probably be very easy (not using all C++ features, but just selected ones), yet it did not happen. I think that C++ is better than C, but C is not that bad, even for large projects.

And the Kernel devs would probably get really annoyed if you try to push this kind of name-spacing.

> C++ would probably be very easy

Not necessary, besides some small? problems due to the C++ allowing "more magic optimizations" then C they would switch to a sub-set of C++, and it might be so you would need to communicate to all contributors that a lot of C++ things are not allowed. And it might be easier to simple not use C++. I mean if it would be that easy the kernel likely would have switched.

Re: Learning that you can use unions in C for grouping things into namespaces

#64

Bleurgh. I have a deep soft spot for C, and I'm known to get twisted pleasure from using obscure language features in new ways to annoy people, but this is a level of abuse that even I can't get behind. If you need namespacing, use C++. As much as I love C, it's terrible for large projects.

Linux kernel is large project and clearly C is sufficient for it, given the fact that migrating to C++ would probably be very easy (not using all C++ features, but just selected ones), yet it did not happen. I think that C++ is better than C, but C is not that bad, even for large projects.

> Linux kernel is large project and clearly C is sufficient for it

Sure, and operating systems have been written in assmebly too. The question is whether it would be better than just sufficient if Linux were written in C++, today (ie C++17 or 20, not something old). Switching now probably wouldn't be feasible (even ignoring technical reasons, the kernel developer community is familiar with the C codebase and code standards and bought into it), but if Linux were started today, would it be a better choice?

Maybe the answer is still no and C would still be chosen, but the choice today is very different than it was when Linux was started. Of course, maybe Rust or something would be chosen today instead.

Re: Learning that you can use unions in C for grouping things into namespaces

#65

Anonymous nested structs are also quite useful for creating struct fields with explicit offsets: #include #include #define YDUMMY(suffix, size) char dummy##suffix[size] #define XDUMMY(suffix, size) YDUMMY(suffix, size) #define PAD(size) XDUMMY(__COUNTER__, size) struct ExplicitLayoutStruct { union { struct __attribute__((packed)) { PAD(3); uint32_t foo; }; struct __attribute__((packed)) { PAD(5); uint16_t bar; }; str…

Anytime macros are used for metaprogramming, it's time to reach for a more powerful language.

You might as well have written that "any time you're reaching for C, it's time to reach for a more powerful language".

But if -sadly- you must use C, metaprogramming using macros is not a terrible thing.

Re: Learning that you can use unions in C for grouping things into namespaces

#66
post #11

The first example seems wrong, instead of `struct sub { ... };` what is meant is `struct { ... } sub;`

You're right; thanks for noticing and I've updated the first example. My C is a bit rusty these days and I didn't check it with a compiler the way I should have.

(I'm the author of the linked-to article.)

Re: Learning that you can use unions in C for grouping things into namespaces

#67
post #47

Earlier quoted context omitted.

Type punning/aliasing with unions is well defined in gcc. Linus even has a humorous rant about it on the topic: https://www.yodaiken.com/2018/06/07/torvalds-on-aliasing/ Sure, it's compiler-specific, but I'm already using `__attribute__((packed))` anyways.

All undefined behaviour is well defined for each compiler, what it really means is implementation defined and subject to change without notice or documentation with every compiler version or host os what flags are enabled or a thousand other things. Why use an approach which strictly relies on specific versions of specific compilers, rather than a completely portable and standard compliant struct with char array and…

GCC explicitly states znd documents that type punning through unions will work as expected. This doesn't work by accident. It works very explicitly by design of GCC.

Different GCC versions aren't randomly going to change documented behavior. And when they accidentally do, they will consider it a bug.

Re: Learning that you can use unions in C for grouping things into namespaces

#68

Earlier quoted context omitted.

Anytime macros are used for metaprogramming, it's time to reach for a more powerful language.

I want to be clear about your meaning, because I don’t know if I’m reading your comment correctly. Are you referring explicitly to syntax based, preprocessor macros? Or does your comment extend to other metaprogramming techniques? I am inclined to think you mean the first considering the amount of emphasis on generic programming in D? Just curious.

I'm referring to both syntax based (AST) macros, and text based (preprocessor) macros. The latter, of course, are much worse.

An example of the former is so-called "expression templates" in C++. I've seen them used to create a regular expression language using C++ expression templates. The author was quite proud of them, and indeed they were very clever.

However nice the execution, the concept was terrible. There was no way to visually tell that some ordinary code was actually doing regular expressions.

C++ expression templates had their day in the sun, but fortunately they seem to have been thrown onto the trash pile of sounds-like-a-good-idea-but-oops.

(I wrote an article showing how to do expression templates in D, mainly to answer criticisms that D couldn't do it, not because it was a good idea.)

Re: Learning that you can use unions in C for grouping things into namespaces

#69
post #40
post #27

Earlier quoted context omitted.

the kernel has to live with the choices it made in the 90s, you don't

Yeah they should have upgraded to some restricted subset of C++ or new restrictive language ages ago. I mostly buy the arguments against having exceptions, perhaps even against polymorphism in general, but the argument against destructors, or atomics... hell no.

> ...against polymorphism...

C has polymorphism. Inheritance-based virtual dispatch is just one kind of polymorphism. It's common to wire up polymorphism in C with bespoke data structures using tagged unions it function pointers. Changing an implementation at link time is even a form of polymorphism.

Re: Learning that you can use unions in C for grouping things into namespaces

#70

Earlier quoted context omitted.

Anytime macros are used for metaprogramming, it's time to reach for a more powerful language.

Macros are useful, as long as they're used sparingly. I think that in this case, it's used well - the struct is still perfectly readable, and the sole purpose of it is to make it so that you don't have to manually name the dummy fields. But you could totally just write out dummy1, dummy2, dummy3 etc. yourself if you want to get rid of the macros.

> Macros are useful, as long as they're used sparingly.

Everybody says that. Everybody believes it. And everybody goes to town making a rat's nest with macros, just like that snarl of cables under my desk that resist all attempts to make it nice.

Myself included. I've even written an article about clever C macros. Look, ma! I was so proud of myself.

But then I got older. I started replacing the macros in my C code with regular code. It turns out they weren't that necessary at all. I liked the C code a lot better when it didn't have a single # in it other than #include.

Post reply on HN