3 ms·
You can do dummy defines of structs with the same size as the real one if you want the struct on the stack and encapsulation.
by rightbyte 3y ago
You can do dummy defines of structs with the same size as the real one if you want the struct on the stack and encapsulation.
- e4m2 3y agoI've done this before, works quite well actually, but isn't very popular for some reason. > You can do dummy defines of structs with the same size Don't forget alignment. The general pattern is: https://godbolt.org/z/6je9Yb3rf https://godbolt.org/z/6je9Yb3rf.
- sfpotter 3y agoMaybe I'm missing the idea, but I'm not sure how this idea is supposed to work without using something like alloca. If you have: struct foo; in foo.h and: struct foo { int a; double x; ... }; in foo.c, you won't have sizeof(struct foo) available from bar.c, so your construction won't work in bar.c. You could define a function: size_t sizeof_foo(void); which just returns sizeof(struct foo) from inside foo.c, but since this size is now only known at runtime, you'll need to resort to alloca or VLAs...
- gpderetta 3y agoYou define public_foo in the header with the public members and a appropriately sized byte array for the private members. In the .c file you define private_foo, same a public_foo except that the byte array is replaced with the actual members. You static assert that size and alignment match and cast at function boundaries. You hope not to have violated strict aliasing rules. This is not completely unlike type erasure with small buffer optimization done by some c++ classes like std::function.
- sfpotter 3y agoOK, I understand what you’re doing now. Thanks for clarifying. The big downside here is that you’re leaking the size of the details into your ABI which wouldn’t happen with a fully opaque type… I could see some uses for it but haven’t felt a strong enough need to reach for it before, although it has occurred to me.
- gpderetta 3y agoOf course there is no way around that. A partial mitigation is the same as done for network protocols: reserve some space for future extensions.
- vore 3y agoAt that point you might as well just name your fields like DONTTOUCHTHIS_foo if you’re having to keep the private definition with fields in sync with the opaque public definition (and making sure the alignment and sizing are always in sync with the private one…)