This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Help with bit-field semantics in C and C++
- From: Mike Stump <mrs at apple dot com>
- To: Joe Buck <Joe dot Buck at synopsys dot COM>
- Cc: Roger Sayle <roger at eyesopen dot com>, Mark Mitchell <mark at codesourcery dot com>, gcc at gcc dot gnu dot org
- Date: Tue, 24 Aug 2004 12:28:33 -0700
- Subject: Re: Help with bit-field semantics in C and C++
On Tuesday, August 24, 2004, at 10:51 AM, Joe Buck wrote:
On Tue, Aug 24, 2004 at 11:05:41AM -0600, Roger Sayle wrote:
The problem here is that a C++ enum can hold values outside the range
of it's type.
If it does, the program is not a valid ISO C++ program.
? What? Of course it is.
I think the standard is perfectly clear in this area:
[#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.
[#3] Otherwise, the new type is signed and the value cannot
be represented in it; the result is implementation-defined.
[#4] Each enumerated type shall be compatible with an
integer type. The choice of type is |
implementation-defined,97) but shall be capable of
representing the values of all the members of the
enumeration.
[#1] 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. |
6.2.6.2 Integer types
[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.37)
[#2] For signed integer types, the bits of the object
representation shall be divided into three groups: value
bits, padding bits, and the sign bit. There need not be any
padding bits; there shall be exactly one sign bit. Each bit
that is a value bit shall have the same value as the same
bit in the object representation of the corresponding
unsigned type (if there are M value bits in the signed type
and N in the unsigned type, then M<=N). If the sign bit is
zero, it shall not affect the resulting value. If the sign
bit is one, then the value shall be modified in one of the
following ways:
-- the corresponding value with sign bit 0 is negated;
-- the sign bit has the value -2N;
-- the sign bit has the value 1-2N.
[#3] The values of any padding bits are unspecified.37) A
valid (non-trap) object representation of a signed integer
____________________
37)Some combinations of padding bits might generate trap
representations, for example, if one padding bit is a
parity bit. Regardless, no arithmetic operation on valid
values can generate a trap representation other than as
part of an exception such as an overflow, and this cannot
occur with unsigned types. All other combinations of
padding bits are alternative object representations of
the value specified by the value bits.
type where the sign bit is zero is a valid object
representation of the corresponding unsigned type, and shall
represent the same value.
[#4] The precision of an integer type is the number of bits
it uses to represent values, excluding any sign and padding
bits. The width of an integer type is the same but
including any sign bit; thus for unsigned integer types the
two values are the same, while for signed integer types the
width is one greater than the precision.
[#2] Conversion of an operand value to a compatible type
causes no change to the value or the representation.
[#17] The type char, the signed and unsigned integer types, |
and the enumerated types are collectively called integer |
types. The integer and real floating types are collectively |
called real types. |
[#2] The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type. The size is determined from the type of the
operand. The result is an integer. If the type of the
operand is a variable length array type, the operand is
evaluated; otherwise, the operand is not evaluated and the
result is an integer constant.
? What am I missing?
It is the equivalent of trying to access memory past the end of an
array
? Can you back that up please.
To paraphrase Mike Stump, "undefined" allows us to "rm -rf ~/" or
core dump, I'm not sure if "unspecified" also allows us to seg fault
in the case above?
Yes.
Please back this up.