CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    initializing a POD bitfield struct

    I'm wondering what is the "best" way to initialize a bitfield struct. I have this bitfield, defined as:
    Code:
    struct S
    {
        unsigned int a : 1;
        unsigned int b : 1;
    };
    If I'm "using" the bitfield, I can initialize it easily when declaring it, as so:
    Code:
    int main()
    {
        S s = {0};
    }
    Now, the issue I'm facing is that I want to embed S inside another struct, which I'll name "outer". EG:

    Code:
    struct Outer
    {
        S s;
    };
    I'm wondering what the "best" way to have Outer initialize S is? I've seen a lot of people use the "union" approach:


    Code:
    struct Outer
    {
        Outer()
        {
            u.all = 0;
        }
        union
        {
            unsigned char all;
            S s;
        } u;
    };
    but:
    1. This adds an extra field depth (the union's u)
    2. Does bit hacking, in a way (is the bitfield as large as my field?)


    Ideally, I'd have wanted to initialize the field in my constructor, as so:
    Code:
    Outer::Outer() : s({0})
    However, this would appear to be a C++11 feature only.

    I have, however, "observed" that by simply "empty constructing" s, eg:

    Code:
    Outer::Outer() : s(){} //Initialize s ?
    vs
    Outer::Outer(){}
    Then my bitfield "appears" initialized.

    I'd like to go with this solution, but I'm unsure if I'm just "lucky" in my observations, or if this actually guarantees my bitfield is initialized. Is it?
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: initializing a POD bitfield struct

    Why not define a constructor for S that performs the initialisation?

    Code:
    #include <iostream>
    using namespace std;
    
    struct S
    {
        unsigned int a : 1;
        unsigned int b : 1;
    
    	S() : a(0), b(0) {cout << "init S\n";}
    };
    
    struct Outer
    {
        S s;
    };
    
    
    int main()
    {
    Outer O;
    }
    Last edited by 2kaud; April 14th, 2014 at 05:43 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: initializing a POD bitfield struct

    Quote Originally Posted by 2kaud View Post
    Why not define a constructor for S that performs the initialisation?
    Well, S isn't necessarily something I own. And if at all possible, I'd rather it stay a POD.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  4. #4
    Join Date
    Oct 2008
    Posts
    1,456

    Re: initializing a POD bitfield struct

    Quote Originally Posted by monarch_dodra View Post
    I'd like to go with this solution, but I'm unsure if I'm just "lucky" in my observations, or if this actually guarantees my bitfield is initialized. Is it?
    yes it is ( or not, see below ), s() ( and s{} in c++11 ) denotes value-initialization that for POD types means zero-initialization.

    That said, AFAIR not all c++03 compilers actually follow the rules when subobjects are concerned, take a look at boost doc here for further details ( and a workaround ).

  5. #5
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: initializing a POD bitfield struct

    A bitfield is for most intents and purposes the same as the type it's a number of bits from, as such, initialisation, and aggregation happens exactly the same way as if they weren't bitfields.
    so.
    Code:
    struct Sb
    {
        unsigned int a : 1;
        unsigned int b : 1;
    };
    struct S
    {
        unsigned int a;
        unsigned int b;
    };
    In the above, Sb and S are syntactically equivalent, there's a functional difference in that S.a and S.b have a reduced range of values they can hold. And there is of course a difference in actual memory storage layout.

    you can aggregate initialise the same way as any other struct. The compiler should warn about any values going out of range.
    Code:
    S s = { 15, 3 };  // initialize s.a to 15, and s.b to 3
    Sb sb = { 0, 1 }; // inisialize sb.a to 0 and sb.b to 1
    If a struct/class is part of another struct/class and all rules and requirements of aggregate types apply (applied recursively to members and arrays), then initialisation is done in the usual way.

    Code:
    struct IntDoubleSandSb
    {
      int i;
      double d;
      S s;
      Sb sb;
    };
    
    // initialized as such
    IntDoubleSandSb foo = { 88, 3.1415, { 15,3 }, { 0,1} }; //i=88, d=3.1415, s and sb initialized like above.
    As you can see, there is no syntactical difference in how to initialize a bitfield vs normal non-bitfield members. ALl normal rules for aggregate type initialization apply (recurcively).


    Note that there is no guarantee about how bits in a bitfield get assigned within their larger type. some compilers to it high to low, some low to high. If you need a specific set of bits and need this to be portable, then use explicit masking, not bitfields.

  6. #6
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: initializing a POD bitfield struct

    Quote Originally Posted by superbonzo View Post
    yes it is ( or not, see below ), s() ( and s{} in c++11 ) denotes value-initialization that for POD types means zero-initialization.

    That said, AFAIR not all c++03 compilers actually follow the rules when subobjects are concerned, take a look at boost doc here for further details ( and a workaround ).
    Nice link.

    Quote Originally Posted by OReubens View Post
    A bitfield is for most intents and purposes the same as the type it's a number of bits from, as such, initialisation, and aggregation happens exactly the same way as if they weren't bitfields....
    Thank you very much (both). That was a real complete and helpful answer.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured