Hacker News new | past | comments | ask | show | jobs | submit login

Here is a sample of how you do this in C++ https://godbolt.org/z/W3bMcqM5P



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.


Uh, 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.


The 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.


That 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.


I can't remember if GCC has actually documented their layout choices. Ideally we would pick something documented =)


The rough C equivalent looks like 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


It'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.


I 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.


Yup, 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


I thought you were not able to initialize bitfield members like that in struct. Am I misremembering, was that something else or is it compiler/c++ release dependent?


This is a c++20 feature


Ah right, I tried again

  <source>(6): error C7582: 't': default member initializers for bit-fields requires at least '/std:c++20'
Nice to see they also improved such "legacy" stuff


You can absolutely initialize bitfield members in structs, not sure where your memory is from… maybe it was broken on some specific compiler vendors/versions?


<source>(6): error C7582: 't': default member initializers for bit-fields requires at least '/std:c++20'

It is c++20 apparently https://godbolt.org/z/qvso544dr


Ah, I misunderstood / didn't look properly and failed to notice this is a default value in the struct definition. My bad.


Possible they were just pre-C++11


This has been possible since C89. See 3.5.2.1 of the C89 rationale [0].

It is architecture/compiler dependent though. This is explicitly acknowledged in the rationale document:

“Since some existing implementations, in the interest of enhanced access time, leave internal holes larger than absolutely necessary, it is not clear that a portable deterministic method can be given for traversing a structure field by field.”

[0] https://www.lysator.liu.se/c/rat/c5.html


I think they were referring to the default member initializer, a feature added in C++11 not exclusive to bitfields. I couldn't see any reference to anything similar in what you linked (admittedly, I skimmed though).

For example:

    struct X {
        int defaulted = 1; // 1 is the default member initializer
    };


>I think they were referring to the default member initializer

Ah, that would make more sense. The combination of bitfield and default initializer syntax does look especially odd, since both features are rarely used IME.

>I couldn't see any reference to anything similar in what you linked

Indeed, there is no way to specify default values for a C struct at definition time.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: