Search code examples
c++serializationbitset

Is it ok to use std::bitset in a struct that is written and read from disk?


I need to store bits in files and std::bitset would be perfect for this, because I need many of its operations when I read the structure back again. The class seems to consist of just an array of the bits and no other member data.

So instead of this

BYTE minuteOfDay[(60 * 24 / CHAR_BIT) + ((60 * 24 % CHAR_BIT) ? 1 : 0)];

I could have this:

std::bitset<60 * 24> minuteOfDay;

If the class should change with a future Visual Studio release and I need to read files written with an old version, I guess I could still just copy the old <bitset> header into my project.

But just before making a really stupid decision: Is this idea somehow flawed for a reason I don't foresee right now?


Solution

  • Is this idea somehow flawed ...?

    Yes.

    Firstly, the failure modes: as you guessed, std::bitset might alter its internal representation. Aside from that, it's anyway not (guaranteed to be) a standard layout type, so the initial write is ill-defined. Aside from that, how would you read it back in? Presumably just read into a correctly-aligned buffer and type-pun it? That's illegal too.

    Secondly, the proposed fix: copying your old <bitset> header along is horrible. It won't be part of the actual standard library, and will still inject itself illegally into namespace std. It's entirely possible some other code will use the native std::bitset and lead to horrible errors.

    On top of that, it may simply not work when divorced from its native version of your standard lib.

    Thirdly, correct solutions: either

    1. (de)serialize it to some well-defined format, using the public interface of std::bitset

      note that this is pretty trivial anyway: std::bitset::to_string already exists, and you can re-construct an instance from that string

    2. or write a replacement class which is controlled by you and guaranteed to be trivially serializable. Just because you don't get std::bitset for free doesn't mean you have to bang rocks together use a raw char array.