-
February 14th, 2007, 09:57 AM
#1
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!
-
February 14th, 2007, 10:11 AM
#2
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
-
February 14th, 2007, 10:50 AM
#3
Re: Bit Fields
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.
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()!
-
February 14th, 2007, 10:54 AM
#4
Re: Bit Fields
What about C++ then? Or is the behavior equivalent to that in C99?
Thanks!
-
February 14th, 2007, 10:54 AM
#5
-
February 14th, 2007, 11:06 AM
#6
Re: Bit Fields
SuperKoko, why is type conversion significant to the wrapping behaviour of ++ in this context?
-
February 14th, 2007, 11:21 AM
#7
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...
-
February 14th, 2007, 11:46 AM
#8
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?
-
February 14th, 2007, 12:16 PM
#9
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?
-
February 14th, 2007, 12:34 PM
#10
Re: Bit Fields
As Mitsukai says, why not use % ?
Though you should use % 4 !
-
February 14th, 2007, 12:35 PM
#11
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.
-
February 14th, 2007, 12:51 PM
#12
Re: Bit Fields
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
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:
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.
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()!
-
February 14th, 2007, 12:57 PM
#13
Re: Bit Fields
Man, the standards all use such big words, too hard to understand for me!
So I can use this okay, right?
-
February 14th, 2007, 05:06 PM
#14
-
February 14th, 2007, 05:09 PM
#15
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|