CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18

Thread: Bit Fields

  1. #1
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Bit Fields

    Hey, I'm just wondering if overflowing is defined and portable when used like so:
    Code:
    	struct myData
    	{
    		unsigned short s : 2; //limit range to two bits, i.e., 0 to 3 in base 10
    	}test = {0};
    
    	++ test.s; //1
    	++ test.s; //2
    	++ test.s; //3
    	++ test.s; //0
    	++ test.s; //1
    	++ test.s; //2
    	//etc...
    Is this standard and defined for unsigned types?
    What about signed types?

    Can my program rely on this behavior and still remain architecture-independent?

    Thanks in advance!

  2. #2
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    Re: Bit Fields

    There´s just another huge thread discussing the advantages (or rather disadvantages) of bitfields. As far as I learned from that thread they´re highly non-portable and compiler dependent.

    Regards,
    Guido
    - Guido

  3. #3
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: Bit Fields

    Quote Originally Posted by C99
    A bit-field is interpreted as a signed or unsigned integer type consisting of the specified
    number of bits.105) If the value 0 or 1 is stored into a nonzero-width bit-field of type
    _Bool, the value of the bit-field shall compare equal to the value stored.

    6.3.1.3 Signed and unsigned integers
    1 When a value with integer type is converted to another integer type other than _Bool,if
    the value can be represented by the new type, it is unchanged.
    2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
    subtracting one more than the maximum value that can be represented in the new type
    until the value is in the range of the new type.49)
    So, in C this is portable for unsigned bit-fields.
    For signed bit-fields, results are implementation-dependent:

    From C99, About conversions to a from any integer type to a signed integer type if the value can't be represented in the new type.
    Quote Originally Posted by C99

    3 Otherwise, the new type is signed and the value cannot be represented in it; either the
    result is implementation-defined or an implementation-defined signal is raised.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  4. #4
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Re: Bit Fields

    What about C++ then? Or is the behavior equivalent to that in C99?

    Thanks!

  5. #5
    Join Date
    Aug 2005
    Location
    Netherlands, The
    Posts
    2,184

    Re: Bit Fields

    why not use variable % 3

  6. #6
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: Bit Fields

    SuperKoko, why is type conversion significant to the wrapping behaviour of ++ in this context?
    My hobby projects:
    www.rclsoftware.org.uk

  7. #7
    Join Date
    Aug 2005
    Location
    Netherlands, The
    Posts
    2,184

    Re: Bit Fields

    because

    Code:
    ++ test.s; //1
    	++ test.s; //2
    	++ test.s; //3
    	++ test.s; //0
    	++ test.s; //1
    	++ test.s; //2
    might become.

    Code:
    ++ test.s; //-0
    	++ test.s; //-1
    	++ test.s; //-2
    	++ test.s; //0
    	++ test.s; //-0
    	++ test.s; //-1
    i think...

  8. #8
    Join Date
    Dec 2003
    Location
    Middletown, DE
    Posts
    67

    Re: Bit Fields

    The data type is 'unsigned int', so it is not possible to be negative. I would expect that it should function just the same as any other unsigned int (or signed int for that matter), but with more or less bits of resolution. (off topic, what is -0?)

    The question of how it 'should' work shall be defined by the C or C++ specification. Unfortunately, this comes at a price from ANSI, even for the soft copy.

    I have a soft copy of Straustroup's "The C++ Programming Language", but I can't find any reference to bit fields in structures.

    I'm not sure why so many readers are concluding that bit fields are non portable. If the code conforms with the C or C++ specification AND the desired compilers support the specification properly, it is portable. Does anyone have any proof of the non-conformance of bitfields?

  9. #9
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Re: Bit Fields

    Okay, so what's the final say?

    Can my program rely on bit field data wrap around behavior?

    I am going to be using an unsigned char with a 3 bit field in C++, will it be portable?

  10. #10
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: Bit Fields

    As Mitsukai says, why not use % ?

    Though you should use % 4 !
    My hobby projects:
    www.rclsoftware.org.uk

  11. #11
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Re: Bit Fields

    Some members will be exposed, and I don't want to write any more helper functions that check bounds and reduce the value and what not...

    Bit fields seem like an easy and elegant solution to me.

  12. #12
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: Bit Fields

    Quote Originally Posted by Zaccheus
    SuperKoko, why is type conversion significant to the wrapping behaviour of ++ in this context?
    ++ test.s is equivalent to test.s+=1

    Quote Originally Posted by C99
    The value of the operand of the prefix ++ operator is incremented. The result is the new
    value of the operand after incrementation. The expression ++E is equivalent to (E+=1).
    See the discussions of additive operators and compound assignment for information on
    constraints, types, side effects, and conversions and the effects of operations on pointers.
    test.s+=1 is equivalent to test.s=test.s+1
    3 Acompound assignment of the form E1 op =E2differs from the simple assignment
    expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once.
    This bit-field lvalue test.s has a type... And this type is an integer type on its own, different from all other integer types. This type is described.
    A bit-field is interpreted as a signed or unsigned integer type consisting of the specified
    number of bits.105) If the value 0 or 1 is stored into a nonzero-width bit-field of type
    _Bool, the value of the bit-field shall compare equal to the value stored.
    It might worth looking at integer representations specification (even though this isn't the matter of this post):
    The representations of all types are unspecified except as stated in this subclause.
    2 Except for bit-fields, objects are composed of contiguous sequences of one or more bytes,
    the number, order, and encoding of which are either explicitly specified or
    implementation-defined.
    3 Values stored in unsigned bit-fields and objects of type unsigned char shall be
    represented using a pure binary notation.40)
    ...
    40) A positional representation for integers that uses the binary digits 0 and 1, in which the values
    represented by successive bits are additive, begin with 1, and are multiplied by successive integral
    powers of 2, except perhaps the bit with the highest position. (Adapted from the American National
    Dictionary for Information Processing Systems.) A byte contains CHAR_BIT bits, and the values of
    type unsigned char range from 0 to 2 CHAR_BIT
    -1.
    The lvalue test.s whose type is a bit-field type appears as an operand to an arithmetic operator, so, integer promotion occurs:
    2 The following may be used in an expression wherever an int or unsigned int may
    be used:
    — An object or expression with an integer type whose integer conversion rank is less
    than or equal to the rank of int and unsigned int.
    — A bit-field of type _Bool, int, signed int,orunsigned int.
    If an int can represent all values of the original type, the value is converted to an int;
    otherwise, it is converted to an unsigned int. These are called the integer
    promotions.48) All other types are unchanged by the integer promotions.
    And, it yields an int, the conversion being value-preserving.

    Then, 1 is added and the resulting int is converted back to the bit-field type on the left side of the assignment operator because:
    In simple assignment (=), the value of the right operand is converted to the type of the
    assignment expression and replaces the value stored in the object designated by the left
    operand.
    Then, reading the rules of integer conversions (since int is an integer type and the bit-field type is an integer type too):
    1 When a value with integer type is converted to another integer type other than _Bool,if
    the value can be represented by the new type, it is unchanged.
    2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
    subtracting one more than the maximum value that can be represented in the new type
    until the value is in the range of the new type.49)
    3 Otherwise, the new type is signed and the value cannot be represented in it; either the
    result is implementation-defined or an implementation-defined signal is raised.
    If the value can be represented in the bit-field, it's preserved, otherwise, point (2) is applied:

    For example if test.s==3, test.s+1==4 and this value is converted to 0 by substracting 4 (well, this is a simple reduction modulo 4).

    C++ has similar wording:
    Promotion:
    Quote Originally Posted by C++

    4.5 Integral promotions [conv.prom]
    3 An rvalue for an integral bit-field (_class.bit_) can be converted to
    an rvalue of type int if int can represent all the values of the bit-
    field; otherwise, it can be converted to unsigned int if unsigned int
    can represent all the values of the bit-field. If the bit-field is
    larger yet, no integral promotion applies to it. If the bit-field has
    an enumerated type, it is treated as any other value of that type for
    promotion purposes.
    Quote Originally Posted by C++
    4.7 Integral conversions [conv.integral]

    1 An rvalue of an integer type can be converted to an rvalue of another
    integer type. An rvalue of an enumeration type can be converted to an
    rvalue of an integer type.

    2 If the destination type is unsigned, the resulting value is the least
    unsigned integer congruent to the source integer (modulo 2n where n is
    the number of bits used to represent the unsigned type). [Note: In a
    two's complement representation, this conversion is conceptual and
    there is no change in the bit pattern (if there is no truncation). ]

    3 If the destination type is signed, the value is unchanged if it can be
    represented in the destination type (and bit-field width); otherwise,
    the value is implementation-defined.

    4 If the destination type is bool, see _conv.bool_. If the source type
    is bool, the value false is converted to zero and the value true is
    converted to one.

    5 The conversions allowed as integral promotions are excluded from the
    set of integral conversions.
    Last edited by SuperKoko; February 14th, 2007 at 12:53 PM.
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  13. #13
    Join Date
    Jun 2006
    Location
    M31
    Posts
    885

    Re: Bit Fields

    Man, the standards all use such big words, too hard to understand for me!
    So I can use this okay, right?

  14. #14
    Join Date
    Aug 2005
    Location
    Netherlands, The
    Posts
    2,184

    Re: Bit Fields

    yes, but why not use % 4

  15. #15
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: Bit Fields

    SuperKoko ... does that not simply mean that a 16 bit un/signed bitfield member will behave the same as a 16 bit un/signed short ?
    Last edited by Zaccheus; February 14th, 2007 at 05:16 PM.
    My hobby projects:
    www.rclsoftware.org.uk

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