CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 28
  1. #1
    Join Date
    Apr 2012
    Location
    Slovenia
    Posts
    259

    Bool type problem

    ...
    struct preferences {
    bool likesMusic : 1; // Why the ' : ' sign? Is now the value of likeMucis 1 (or True) ?
    bool hasHair : 1;
    bool hasInternet : 1;
    bool hasDinosaur : 1;
    unsigned int numberOfChildren: 4;
    };
    ....

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

    Re: Bool type problem

    the :1, :4 etc are specifying the number of bits that are used to store the value. So likesMusic is using 1 bit and numberOfChilden is using 4 bits. See http://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx
    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
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Bool type problem

    Like 2Kaud said: this is something called 'bitfields'.
    Avoid using it, it is likely to cause you more headaches than it's worth.

    The idea behind it is that you can use fewer bits and thus use fewer memory in your program, this could be important for very large arrays. On small low usage structs, it's sort of pointless.

    While it may use less memory in storage of the data, it will use more code every time you access one of the variables. so it's a bit of a catch 22 (and one of the headaches I mentioned).

    Also, do NOT use bitfields to do specific masking as there is no guarantee WHICH bits you'll be getting, compilers are free to organize this any way they see fit. (another headache issue)


    In this particular sample, the struct is going to be 8 bytes. If you made the same struct without bitfields, it's also going to be 8 bytes.
    So it's a pretty horribad sample of bitfields since you'll get all the disadvantages and none of the advantages.

  4. #4
    Join Date
    Jul 2013
    Posts
    576

    Re: Bool type problem

    Quote Originally Posted by OReubens View Post
    In this particular sample, the struct is going to be 8 bytes. If you made the same struct without bitfields, it's also going to be 8 bytes.
    How do you know that?

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

    Re: Bool type problem

    Quote Originally Posted by razzle View Post
    How do you know that?
    because it's documented to be that way. You have to find the bits and bobs from a few different places in the manual though.

    Feel free to actually try it out.

  6. #6
    Join Date
    Jul 2013
    Posts
    576

    Re: Bool type problem

    Quote Originally Posted by OReubens View Post
    because it's documented to be that way. You have to find the bits and bobs from a few different places in the manual though.

    Feel free to actually try it out.
    C++ is not defined by some "manual". It's defined by the C++ standard and it states that the allocation of bit-fields is implementation dependent (see 9.6 bit-fields). This means "trying out" may give different answers depending on which C++ implementation you're using.

    Furthermore, the sizes of primitive types such as bool and unsigned int aren't specified by the standard either. It's also implementation dependent.

    Since the OP hasn't specified a certain implementation you simply cannot know the size of the struct, neither with nor without the bit-fields.

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

    Re: Bool type problem

    Regardless of implementation, for a compiler adhering to the standard, you'll get (at least) 8 bytes. And yes, I DO know that.

    which 4x1bit and 1x4bits you get out of the 8 bytes is however compiler dependant and potentially even compiler setting/option dependant.

    There may be an oddball case out there that'll give a sizeof 16, but I can't think of any current one that will.
    Well to be fair, I do have 1 compiler that'll return a size of 256, but that one doesn't really count, it's an extremely niche thing.


    Now tell me you tried it, you expected 1 byte (of maybe 4) and you get 8 instead, and you can't figure out why. :-D
    Last edited by OReubens; September 21st, 2014 at 08:33 AM.

  8. #8
    Join Date
    Jul 2013
    Posts
    576

    Re: Bool type problem

    Quote Originally Posted by OReubens View Post
    Regardless of implementation, for a compiler adhering to the standard, you'll get (at least) 8 bytes. And yes, I DO know that.
    As I've shown, you have no support for that claim in the C++ standard.

    You simply cannot tell the size of the struct with or without the bit-fields unless you know which exact compiler is being used.

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

    Re: Bool type problem

    I do have support in the standard. Feel free to find it. Or alternatively, show me the 32-bit or higher compiler where it's less than 8.

    This is actually part of the "headache" issues I pointed out already and why you're better off to avoid bitfields entirely. They just don't work the way most programmers expect them to work. And even if you do figure it out, it's still not going to be fully portable.

    If you really need actual bitmasking, or packing bits into a series of bytes. do it "the hard way", don't rely on bitfields.

  10. #10
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Bool type problem

    Quote Originally Posted by OReubens
    I do have support in the standard. Feel free to find it.
    I think the onus is on you to support your claim. razzle mentioned clause 9.6, and it reads:
    Quote Originally Posted by C++11 Clause 9.6 Paragraph 1 (part)
    Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit.
    Unless you show evidence to the contrary, it does seem that your claim that the standard guarantees that "the struct is going to be 8 bytes" (at least) is unfounded in this case.

    Quote Originally Posted by OReubens
    Or alternatively, show me the 32-bit or higher compiler where it's less than 8.
    This hints that your claim that the standard supports you "regardless of implementation" actually is false, since if you are sure that the standard mandates it, then there is no need for a "32-bit or higher compiler" stipulation.

    It probably would be better to just state that for all 32-bit or higher compilers that you are aware of, the struct size is going to be at least 8 bytes. Such a claim cannot be disputed.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  11. #11
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Bool type problem

    The result is also highly variable on the types used.
    (Visual Studio 2013)

    Code:
    struct preferences {
    bool likesMusic : 1;
    bool hasHair : 1;
    bool hasInternet : 1;
    bool hasDinosaur : 1;
    unsigned int numberOfChildren: 4;
    };
    
    sizeof = 8
    Code:
    struct preferences {
    char likesMusic : 1;
    char hasHair : 1;
    char hasInternet : 1;
    char hasDinosaur : 1;
    unsigned int numberOfChildren: 4;
    };
    
    sizeof = 8
    Code:
    struct preferences {
    int likesMusic : 1;
    int hasHair : 1;
    int hasInternet : 1;
    int hasDinosaur : 1;
    int numberOfChildren: 4;
    };
    
    sizeof = 4
    Code:
    struct preferences {
    char likesMusic : 1;
    char hasHair : 1;
    char hasInternet : 1;
    char hasDinosaur : 1;
    char numberOfChildren: 4;
    };
    
    sizeof = 1
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

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

    Re: Bool type problem

    AFAIR, note that bool and enum bitfields follow special rules making OReubens claim essentially correct ( I cannot quote the std at the moment (I'm typing from a mobile device ) ) and forcing the int to be aligned on the machine natural boundary ( ie, for >=32bit this means >= 8 bytes for that struct ) ...

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

    Re: Bool type problem

    Quote Originally Posted by laserlight View Post
    This hints that your claim that the standard supports you "regardless of implementation" actually is false, since if you are sure that the standard mandates it, then there is no need for a "32-bit or higher compiler" stipulation.
    This is just there because on a 16bit compiler, the size of an int will be different.
    in case you want to know,
    on a 16bit compiler, the sizeof will be either 4 or 6, depending on the compiler used.

    that is also the exact same reason for the 'exception' I made about that one other compiler where the size will be 256 (#7) because on that particular compiler, an int is 128bytes (1024bits). yes, such beasts do exist.

    It probably would be better to just state that for all 32-bit or higher compilers that you are aware of, the struct size is going to be at least 8 bytes. Such a claim cannot be disputed.
    Nope, it is in the spec, but you won't find it if you only look at the specific topic about bitfields because it's not in there.

    I am going to accept that I might be incorrectly interpreting the part I'm alluding to, but if so, every single C and C++ compiler I've used to date (and that's a considerable amount) seem to be interpreting that part in exactly the same way.

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

    Re: Bool type problem

    Quote Originally Posted by JohnW@Wessex View Post
    The result is also highly variable on the types used.
    (Visual Studio 2013)
    this is actually at the core of the reasoning. And it has everything to do with the "members of structures" and "alignment".

    bitfields only accumulate into a larger type in so far as the larger type of subsequent fields is the same.
    so if you have a bool bitfield, followed by a int bitfield, that's 2 distinct types, and thus the bits are not packed together.

    Also note that alignment must be respected, so the int (32bit) will be 4byte aligned regardless that you only use 4 bits. so 4 bools, potentially packed into 1 byte, causes 3 padding bytes. result. 8 bytes whichever way y ou turn it.

    is the headache setting in yet ?


    then allow me to continue.
    - It is perfectly acceptable according to the standard that a compiler entirely ignores the bitfield width and just uses separate types, each aligned and just applies clipping. there is no requirement for packing bits.
    - a bool is essentially a 1bit type but has to be stored into a sizeof(char) to fulfill the requirements of type & references. A compiler is free to allow packing of bools into a char, or see a bool as a 1bit type which as a result can't be packed at all.

    More if you wanna see heads exploding.
    I'll just repeat myself... "avoid bitfields", there's better ways to do things.

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

    Re: Bool type problem

    Quote Originally Posted by OReubens View Post
    bitfields only accumulate into a larger type in so far as the larger type of subsequent fields is the same.
    so if you have a bool bitfield, followed by a int bitfield, that's 2 distinct types, and thus the bits are not packed together.

    Also note that alignment must be respected, so the int (32bit) will be 4byte aligned regardless that you only use 4 bits. so 4 bools, potentially packed into 1 byte, causes 3 padding bytes. result. 8 bytes whichever way y ou turn it.

    is the headache setting in yet ?
    Oh wow! I had no idea!

    Code:
    #include <iostream>
    
    struct S
    {
      int  a00 : 1;
      char a01 : 1;
      int  a02 : 1;
      char a03 : 1;
      int  a04 : 1;
      char a05 : 1;
      int  a06 : 1;
      char a07 : 1;
      int  a08 : 1;
      char a09 : 1;
      int  a10 : 1;
      char a11 : 1;
      int  a12 : 1;
      char a13 : 1;
      int  a14 : 1;
      char a15 : 1;
      int  a16 : 1;
      char a17 : 1;
      int  a18 : 1;
      char a19 : 1;
    };
    
    int main()
    {
      std::cout << sizeof(S) << std::endl;
      return 0;
    }
    This print 80. 80 bytes! For 20 bits!

    I know for a fact nobody in my organization knows about this, and that we probably have very bloated structs in our code.

    Nobody ever checks anything with static asserts...
    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.

Page 1 of 2 12 LastLast

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