This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]