5 ms·
Wow... I thought I had seen a lot of strange C++ code but I have _never_ seen packed structs using this syntax: struct X { type alias : numeric_value = false;
by flumpcakes 4y ago
Wow... I thought I had seen a lot of strange C++ code but I have _never_ seen packed structs using this syntax:
struct X {
type alias : numeric_value = false;
...
}
I love the power of C++ but there is _so much_ to the language. I'm sure there would also be some template meta programming solution even if this syntax was available.
- Joker_vD 4y agoUh, that's standard C89. You know, the bit fields? Except for the "false" keyword, that's from stdbool.h and you need C99 for that to reliably exist.
- rrampage 4y agoThe rough C equivalent looks like https://godbolt.org/z/YqGPa7ecd https://godbolt.org/z/YqGPa7ecd , using _Static_assert ( available C11 on wards and as a GCC built-in from 4.6 ) with no default values for the struct members
- stephencanon 4y agoThe only real problem with C (and C++) bitfields is that the standard doesn’t say anything about how they’re laid out in memory, which unfortunately makes them mostly useless unless you either don’t care about layout or you’re targeting one specific compiler and that compiler documents its choices and doesn’t break them in a few years. Sign-extension of 1-bit fields also messes people up all the time, but that’s “just” an easy-to-fix bug.
- pclmulqdq 4y agoThat is a really big problem in some applications. I wish the C committee would come out and say "use the layout that GCC 11 .x.x does" to make these a lot more usable.
- stephencanon 4y agoI can't remember if GCC has actually documented their layout choices. Ideally we would pick something documented =)
- scaredginger 4y agoIt's probably tough to find a metaprogramming solution to this, for two reasons: 1. Addressing happens at the byte level, not the bit level, so a type can't begin on any bit. You'd have to do your own addressing, such as in std::bitset. 2. For now, there's no reflection in the language, so you can't really assign names to members in a general way (hello, preprocessor). A solution might be to index by type; something like the following: struct BitA{}; struct BitB{}; using ExampleBitFields = BitFields<BitA, BitB>; bool checkBitA(const ExampleBitFields& x) { return x[BitA{}]; } However, this has a lot of downsides.
- pclmulqdq 4y agoI have done similar things a few times, and like JSON handling, the optimal API does not seem to be the same for every intended use. Size-focused cases want different things than speed-focused ones, and you need to deal with sign extension, etc.
- scaredginger 4y agoYup, I'd be very wary of all the template instantiation going on here. Sadly, I often find codegen is the most reasonable solution in a given situation. I wish we had a decent macro system, like Rust's