5

How do you initialize the values of the following struct in a constructor to defined values?

Both options shown in my code example seem to be a bit ugly....

struct T_AnlagenInfo01
{   
    // Option A
    T_AnlagenInfo01() : fReserve80_0(0), fReserve80_1(0),.... {}; 

    // Option B
    T_AnlagenInfo01()
    { 
        memset(this, 0, sizeof(T_AnlagenInfo01));
    } 

    unsigned long fReserve80_0                          : 1;        
    unsigned long fReserve80_1                          : 1;        
    unsigned long fReserve80_2                          : 1;        
    unsigned long fReserve80_3                          : 1;        
    unsigned long fReserve80_4                          : 1;
    unsigned long fReserve80_5                          : 1;
    unsigned long fReserve80_6                          : 1;
    unsigned long fReserve80_7                          : 1;

    unsigned long fReserve81_0                          : 1;        // 81   
    unsigned long fReserve81_1                          : 1;        
    unsigned long fReserve81_2                          : 1;        
    unsigned long fReserve81_3                          : 1;
    unsigned long fReserve81_4                          : 1;
    unsigned long fReserve81_5                          : 1;
    unsigned long fReserve81_6                          : 1;
    unsigned long fReserve81_7                          : 1;
};
Ronald McBean
  • 1,417
  • 2
  • 14
  • 27
  • Be careful with the `memset` alternative if you have virtual functions in the class, as it will overwrite the vtable as well. – Some programmer dude Jan 17 '12 at 13:23
  • Horrible naming conventions. Legacy, I guess? Anyways, `fReserve80_0(0)` is the standard way, and actually less ugly and more maintainable and typesafe than memset. – Sebastian Mach Jan 17 '12 at 13:31
  • @phresnel: Ooooh yes... :-( Legacy code that stopped working when used on a new faster machine. – Ronald McBean Jan 17 '12 at 13:33
  • Possible duplicate of [How to initialize bitfields with a C++ Constructor?](https://stackoverflow.com/questions/3562964/how-to-initialize-bitfields-with-a-c-constructor). – Some Guy Jun 13 '20 at 09:52

3 Answers3

4

One obvious solution would be to put all of the bits in a separate structure, which is a member of your structure, and copy initialize that from a static member, e.g.:

struct T_AnlagenInfo01
{
    struct Bits
    {
        unsigned long fReserve80_0 : 1;
        unsigned long fReserve80_1 : 1;
        //  ...
    };
    Bits myBits;
    static Bits initialBits;

    T_AnlagenInfo01 : myBits(initialBits) {}
};

T_AnlagenInfo01::Bits T_AnlagenInfo01::initialBits = {};

This would even allow for certain bits to have a value different from 0.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
2

I think Option A isn't that bad. If you agree with the trouble of having different named variables for each bit, then be so kind to initialize them separately as well. Option B seems like a dirty hack and may even be technically Undefined Behavior (I am not totally sure though). In any case, better safe than sorry. Come to think of it, there's a fat chance that it's actually UB because your type is not a POD.

Please note that my answer holds if you wanted to have different named variables for each bit. You could always have a std::vector<bool> or std::bitset<N> or boost::dynamic_bitset as a member instead of all these bit-fields.

Community
  • 1
  • 1
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
0

Option C

struct T_AnlagenInfo01
{
   bitset<14> mybits;
}

You can use the bitset instead of bit fields and you don't have to do anything special for initialization if you want them all unset. And instead of a class with 14 members you can provide member functions to do the same job.

parapura rajkumar
  • 24,045
  • 1
  • 55
  • 85