Live data from Hacker News

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

utcc.utoronto.ca

91–100 of 150 posts

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

#91
post #86

Earlier quoted context omitted.

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 n…

> And the Kernel devs would probably get really annoyed if you try to push this kind of name-spacing. Actually, they use it themselves. [0] [0] https://lwn.net/SubscriberLink/864521/d704bdcced0c5c60/

Yes, it's scary.

But it's also not used but to .

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

#92
post #9
post #4

Earlier quoted context omitted.

C++ namespaces are unrelated to this. They don’t accomplish the same thing.

The goal of inline namespaces is exactly to allow for migrating libraries across versions.

That's nice, but the blog post doesn't say anything about migrating libraries across versions? Looking at the comment thread, I see tialaramex's sibling comment suggested the blog post was about migration, but it's not.

I suppose migration is another possible use case for the union trick, and for that case C++ inline namespaces can be used as part of an implementation that achieves a broadly similar goal, but in a completely different way. As tialaramex notes, with inline namespaces you still end up with two different types.

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

#93

Earlier quoted context omitted.

> is not a terrible thing It is a terrible thing. It's possible to do without them, and you'll like your code better. Your symbolic debugger and syntax directed editor will work properly. The poor schlub who has to fix the bugs in your code after you leave will be grateful. Your spouse will be happy and your children will prosper. For example, #define foo(x) ((x) + 1) replace with: int foo(int x) { return x + 1; } Th…

The optimizer will delete bar() if FOO is a manifest constant that is not 3. Yes, but the compiler won't delete it and complain if bar is not defined. if constexpr is not a direct replacement for if macro

> the compiler won't delete it and complain if bar is not defined

    extern void bar();
will define it to the satisfaction of the compiler. The linker won't complain if the compiler removes the call to it.

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

#94
post #45

Earlier quoted context omitted.

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

Doesn’t work in a lot of cases unfortunately. If you’re writing a library designed to be consumed by other languages you’re stuck with writing C abi compatible code which can be written in other languages that can “extern” them but it puts limits on what’s possible in those libraries.

One thing I do is to make my own interface to the 3rd party library with the ugly interface. Then that interface file is only one that sees it.

It also may be true that one can't replace every use of the preprocessor. That shouldn't stop replacing what one can.

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

#95
post #55
post #48

Earlier quoted context omitted.

No: from https://en.cppreference.com/w/cpp/language/union . The union is only as big as necessary to hold its largest data member. The other data members are allocated in the same bytes as part of that largest member. The details of that allocation are implementation-defined but all non-static data members will have the same address (since C++14). It's undefined behavior to read from the member of the union that wasn…

The post is about C, not C++. My comment stands, as the original post has two structs in a union, and they start the same way, so it’s exactly the case covered in the C11 Standard.

It's actually weirder than that. The C standard allows type punning through unions, but not because of the clause you mentioned. It allows it because of footnote 95:

> If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’)

This is broader than the common initial subsequence clause, and allows punning between completely different types, e.g. int, char[4], and float.

You might ask, what is the point of the "common initial subsequence" rule then? It's to allow certain accesses that don't go directly through the union, so the compiler doesn't know for sure whether there's a union involved. Only problem is that all major compilers completely ignore this rule. [1] (But they do implement the first clause I mentioned, where the accesses do go through the union.)

[1] https://stackoverflow.com/questions/34616086/union-punning-s...

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

#96
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…

... ? That's definitely not true, both anonymous structs and enums work fine in c++. https://wandbox.org/permlink/ICaQJXCaVOt9mXdP

No, they are forbidden by the standard (take a look at cppreference). Some compilers implement the C behavior as an extension, so tell your compiler to follow the standard strictly.

I don’t use extensions, even convenient ones, as I have to be able to run my code on a variety of compilers. If you don’t have to do that, some extensions (like this one) are really handy.

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

#97
post #82
post #48

Earlier quoted context omitted.

No: from https://en.cppreference.com/w/cpp/language/union . The union is only as big as necessary to hold its largest data member. The other data members are allocated in the same bytes as part of that largest member. The details of that allocation are implementation-defined but all non-static data members will have the same address (since C++14). It's undefined behavior to read from the member of the union that wasn…

You've mentioned this several times on this page, but this is still incorrect. The C standard references "struct or union" all over the place because the two are so similar. The distinction is of course made clear in multiple places, but one that seems relevant here is: > As discussed in 6.2.5, a structure is a type consisting of a sequence of members, whose storage is allocated in an ordered sequence, and a union is…

> The size of a union is sufficient to contain the largest of its members.

Correct me if I'm wrong, but there is no part of the C spec that says this:

When initializing a union member that is smaller than the largest member, the remaining bytes will always automatically be initialized to zero.

If I'm right then the following caveat must be added to your statement:

> A pointer to the union points to each of its members, and can be dereferenced to access it.

... if and only if the member which was originally initialized is at least as large as the other member being accessed.

In other words, if you write your program in a way that ensures it will only compile when all union members are exactly the same size, and you have mandatory tooling to make sure that any changes to said union follow the same rule by force of compilation errors, then and only then can you claim what you claimed without the threat of undefined behavior.

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

#98
post #75

Earlier quoted context omitted.

Agree except the last example - the clarity of intent that you want a conditional compilation is lost. Also, non-optimized debug builds are affected.

> clarity of intent Conditional compilation is an optimization, not a semantic intent. > non-optimized debug builds are affected The code size will be larger. Doesn't matter.

> Conditional compilation is an optimization, not a semantic intent.

Why can't it have semantic intent? I frequently use it for cross-platform adjustments, and those don't usually compile on the defined-away platform.

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

#99
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…

> All undefined behaviour is well defined for each compiler

This is not true.

> what it really means is implementation defined

Implementation-defined behavior is a thing in the standard and is separate from undefined behavior.

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

#100

Earlier quoted context omitted.

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…

Can you link to it? We're using expression templates on a new library and I find it useful.
Post reply on HN