Live data from Hacker News

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

utcc.utoronto.ca

11–20 of 150 posts

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

#12
post #2

Doesn’t matter for C, but in C++ this could make your contexpr functions UB since you can only use one member of a union in constexpr contexts (the “active” member).

Triggering UB is a compiler error in constexpr code.

https://shafik.github.io/c++/undefined%20behavior/2019/05/11...

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

#14
post #12
post #2

Doesn’t matter for C, but in C++ this could make your contexpr functions UB since you can only use one member of a union in constexpr contexts (the “active” member).

Triggering UB is a compiler error in constexpr code. https://shafik.github.io/c++/undefined%20behavior/2019/05/11...

True, you’ll hopefully get a compiler error.

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

#15
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; };
            struct __attribute__((packed)) { PAD(13); uint64_t baz; };
        };
    };
    
    int main(void) {
        // offset foo = 3
        // offset bar = 5
        // offset baz = 13
        printf("offset foo = %d\n", offsetof(struct ExplicitLayoutStruct, foo));
        printf("offset bar = %d\n", offsetof(struct ExplicitLayoutStruct, bar));
        printf("offset baz = %d\n", offsetof(struct ExplicitLayoutStruct, baz));
        return 0;
    }

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

#17
post #8

Earlier quoted context omitted.

Hmm. How do C++ namespaces help with the structure naming problem in this example? They seem completely orthogonal. C++ namespaces are a way to avoid library A's symbol "cow" clashing with library B's symbol "cow" without everything being named library_a_cow and library_b_cow all over the place which is annoying. I agree C would be nicer with such a namespace feature. However this technique is about what happens when…

You can use inline namespaces for versioning symbols. https://www.foonathan.net/2018/11/inline-namespaces/

First of all, C++ 11 may feel like thirty years ago, and certainly some of its proponents look thirty years older than they did at the time, but it was only ten years ago. C++ namespaces date to standardisation work (so after the 1985 C++ but before the 1995 standard C++) but they don't get this job done. Inline namespaces are a newer feature.

Secondly this technique does something different. The C hack doesn't touch the old code. But this "inline namespace" trick means old code has to explicitly opt into this backward compatibility fix or else it might blow up.

Lastly, I didn't try this, but presumably you did. Are the two separately namespaces classes the "same thing" as far as type checking is concerned? A vital feature of this union trick is that it's just one structure, it type checks as the same structure because it is the same structure. At a glance, I think the C++ solution results in two types with similar names, so that would fail type checking.

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

#18

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…

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 declarations, again a waste when you will only have a single object of a given type.

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

#19

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…

Do foo and bar deliberately overlap?

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

#20
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.
Post reply on HN