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.
Learning that you can use unions in C for grouping things into namespaces
41–50 of 150 posts
Re: Learning that you can use unions in C for grouping things into namespaces
#42Earlier quoted context omitted.
Yes, I was looking to demonstrate the flexibility of the approach by including overlapping fields.
If you write to either, accessing the other, even on the overlap, is undefined behaviour
https://www.yodaiken.com/2018/06/07/torvalds-on-aliasing/
Sure, it's compiler-specific, but I'm already using `__attribute__((packed))` anyways.
Re: Learning that you can use unions in C for grouping things into namespaces
#43Anonymous 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…
There are two kinds of undefined behaviour being invoked in using this. Its a horrible idea and a horrible code smell, get rid of it if you ever see something like this.
Re: Learning that you can use unions in C for grouping things into namespaces
#44Earlier 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…
Use a enum in a namespace, or anonymous namespace
static obj& some_call (obj& o, enum struct { abandon, save } disposition) { ... };
This is a common case (and should be more common) to avoid using an obscure boolean flag, which can lead to bugs. It shouldn't need a name.An anonymous namespace just means the name itself won't leak out; under C++ rules I need the name even to specify the enum tag, which is absurd.
Re: Learning that you can use unions in C for grouping things into namespaces
#45Anonymous 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.
Re: Learning that you can use unions in C for grouping things into namespaces
#46This is probably a terrible idea, remember that if you have written one member of a union, all other members remain public, yet accessing any of them in any way is undefined behaviour. This is made way worse by most compilers mostly choosing to let you do what you think it will. They just dont guarantee they always will or in all cases.
Re: Learning that you can use unions in C for grouping things into namespaces
#47Earlier quoted context omitted.
If you write to either, accessing the other, even on the overlap, is undefined behaviour
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.
Re: Learning that you can use unions in C for grouping things into namespaces
#48This is probably a terrible idea, remember that if you have written one member of a union, all other members remain public, yet accessing any of them in any way is undefined behaviour. This is made way worse by most compilers mostly choosing to let you do what you think it will. They just dont guarantee they always will or in all cases.
I believe you are mistaken. The C11 standard, section 6.5.2.3 "Structure and union members" pgf 6, says "One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declar…
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't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.
What 6.5.2.3 simplifies is the use of unions of the type:
struct A{int type; DataA a;}
struct B{int type; DataB b;}
union U{A a;B b};
U u;
switch(u.type)...
Its not what is beeing used here.
std::variant is designed to deprecate all legitimate uses of union
Re: Learning that you can use unions in C for grouping things into namespaces
#49Re: Learning that you can use unions in C for grouping things into namespaces
#50Earlier quoted context omitted.
There are two kinds of undefined behaviour being invoked in using this. Its a horrible idea and a horrible code smell, get rid of it if you ever see something like this.
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.
Packed is technically not a undefined behaviour, but it is certainly a trap. Especially because the compiler macros leads people to make defines which select packed by compiler automatically. Then the special case of didn't recognize compiler is just left empty, meaning compiles but no longer does what you think.