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++


Joe Buck <Joe.Buck@synopsys.COM> writes:

| Joe Buck <Joe.Buck@synopsys.COM> writes:
| > | I agree with you so far; (E)n might be 7.
| 
| On Wed, Aug 25, 2004 at 01:29:50AM +0200, Gabriel Dos Reis wrote:
| > I disagree that the enum object would have value 7, as 7 is not an
| > enumeration (E) value.
| 
| I attempted to clarify this in the followup; I meant to say that an
| implementation might produce code that still has a 7 at that point,
| because the behavior of the program is unspecified.  Or are you claiming
| that the compiler is *required* to emit code that will transform the 7
| into one of [0,3]?

At any single time, the value of an enum -- other than that of an
uninitialized variable -- is always a valid enumeration value, which is
always in the range of enumration value, here [0.3].

If you bitor or bitand or bitxor two enum values together, you will
always get back an enumeration value that is in the bit-sized full
range of the underlying type, therefore a valid enumration value.  By
the very type rules that governs C++ enums.

Now, if you attempt to store an out-of-range value in an enumeration,
the very same quote we repeatedly made says that the value stored is
an enumration value -- except that is unspecified.

Consequently, if you attempt to store 7 in an enum under discussion,
it *shall* get projected to the range [0,3].

| > | The next question, then, is whether, despite this, a compiler is allowed
| > | to implement a switch on a variable of type E as a jump table, in such a
| > | way that a value outside of [0,3] malfunctions (jumps to a random address).
| > 
| > By the type properties confered to E, any value of that type is in the
| > range [0,3]. 
| 
| For a conforming program.  Here we have a program that attempts to assign
| an out-of-range value to an enum.

The program is conforming but is depending on an unspecified behaviour
-- which we're not requirement to document.  This is close to
undefined behaviour except that we can't "rm -rf ~/" or crash as said
by Mike. 
The compiler is at fault here because it is failing to project the
value as required and later it is using an invalid value it emitted
earlier. 

The very source of where this type violation might appear is
well-known:  It is when (static_)casting a non-enum value or a value 
that manisfestly does not come from usual enum-value preserving
operations like bitor, bitand or bitxor.

| > | Let's leave to one side whether this is a good idea.  Is it permitted?
| > 
| > That can't happen.
| 
| But it does happen.

Only because the compiler failed earlier to properly project the value
to the range.

|  Is that a bug we must fix?

Yes, in as much as we're not allowed to crash.  The fix consists
in projecting the value to the proper range -- this need doing only
when the source value manifestly comes from non enum-value preserving
operations or unknown sources.

|  If so, we have to slow
| down the compiler to prevent any conversion from an int to an enum from
| assigning an out-of-range value.

For most cases, we slow down the compiler only in cases where the
programmer was already attempting to store an out-of range value in
the enum -- which is kind of type violation in the first place.
This does not happen for the majority of common cases.

Notice that, on purpose C++ has forbidden implicit conversion from int
to enums and between distinct enumerations.  Furthermore it makes the
last point the same as here, very explicitly.
5.2.9/7
  A value of integral or enumeration type can be explicitly converted
  to an enumeration type. The value is unchanged if the original value
  is within the range of the enumeration values (7.2). Otherwise, the
  resulting enumeration value is unspecified.

This is at least the second type, the C++ standard is stating this.

Instead of elaborating on whether our faces should become blue, we
might probably just consider what the standard says at various places,
very consistently. 

-- Gaby


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