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


Roger Sayle wrote:

On Tue, 24 Aug 2004, Joe Buck wrote:


[ issues connected with limited range of C++ enums ]
On Tue, Aug 24, 2004 at 10:32:39AM -0600, Roger Sayle wrote:


I'm happy with the explanations so far. The next question is, if
the middle-end is supposed to treat loads, stores and comparisons
of these types identically to the underlying integer type for the
enumeration, is there a benefit for setting TYPE_PRECISION lower
than GET_MODE_BITSIZE for C++'s enumerated types?


I think that the middle end should, at least by default, try to generate
the best code possible for conformant programs that use C++ enums.  In
most cases, that probably means treating them as belonging to the
underlying integer type; the exception would be where the limited range
allows for, say, more efficient switch statements, or to determine that
some code is unreachable.

It's possible to have the compiler generate enum range-checking code, but
doing so would seem inconsistent with how we do everything else. It would
only make sense in the context of a bounds-checking compiler that would
also handle array bounds and the like.



The problem here is that a C++ enum can hold values outside the range of it's type.

enum E { zero = 0x00, one = 0x01 };

void test(int n)
{
 enum E x;

 x = (E)n;
 switch (x)
 {
 case zero:  foo();  break;
 case one:   bar();  break;
 }
}

int main()
{
 test(255);
 return 0;
}


In the above code, the enumeration makes "x" is a single bit
wide, and all possible values of the width are handled in the switch.
If we were to omit the range tests, and use a table jump, the above
code would probably core dump for values of x such as 255.


I think that dumping core is OK.

What's unspecified is what happens when you convert 255 to E.

We can specify that by saying that the value you get is the same as if you convert 255 to the underlying integer type of E. I don't think that the standard is saying, or means to say, that the compiler must actually bring the value into the allowed range of E.

The EDG front end, with --short-enums, converts:

enum E { e_0 = 0, e_1 = 1 } e;
void f() { e = (E)12; }


to this C code:

void _Z1fv(void) { e = ((enum E)(12)); }

which certainly suggests that they are doing any kind of truncation.

Now, are we allowed to dump core on the switch? I believe so, because the standard guarantees that the values of the enumeration type are limited. However, the standard is not 100% clear on this issue, sadly. Perhaps we should have a DR.

--
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com


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