Paweł Sikora wrote: > typedef enum { X, Y } E; > int f( E e ) > { > switch ( e ) > { > case X: return -1; > case Y: return +1; > } > } > > In this example g++ produces a warning: > > e.cpp: In function ‘int f(E)’: > e.cpp:9: warning: control reaches end of non-void function > > Adding `default' statemnet to `switch' removes the warning but > in C++ out-of-range values in enums are undefined.
Not quite. They are unspecified; see below. > I see no reason to handling any kind of UB ( especially this ). > IMHO this warning is a bug in C++ frontend. This is a tricky issue. You are correct that the values of "E" are exactly { 0, 1 } (or, equivalently, { X, Y }). But, the underlying type of the enumeration is at least "char". And, the standard says that assigning an integer value to enumeration type has unspecified behavior if it outside the range of the enumeration. So: E e; e = (E) 7; has unspecified behavior, which is defined as: "behavior, for a well-formed program construct and correct data, that depends on the implementation. The implementation is not required to document which behavior occurs." Because the program is unspecified, not undefined, the usual "this could erase your disk" thinking does not apply. Unspecified is meant to be more like Ada's bounded errors (though not as closely specified), in that something vaguely sensible is supposed to happen. For GCC, what happens (though we need not document it) is that the value is converted to the underlying type -- but not masked down to { 0, 1 }, because that masking would be costly. So, "((int) e == 7)" may be true after the assignment above. (Perhaps, in some modes GCC may optimize away the assignment because it will "know" that "e" cannot be 7, but it does not do so at -O2.) So, now, what should we do about the warning? I think there are good arguments in both directions. On the one hand, portable programs cannot assume that assigning out-of-range values to "e" does anything predictable, so portable programs should never do that. So, if you've written the entire program and are sure that it's portable, you don't want the warning. On the other hand, if you are writing a portable library designed to be used with other people's programs, you might every well want the warning -- because you can't be sure that they're not going to pass "7" in as the value of "e", and you may want to be robust in the face of this *unspecified* behavior. In practice, this warning from GCC is keyed off what it thinks the effective range of "E" is. If it starts assuming that "e" can only have the values { 0, 1 }, it will also stop warning about the missing case. It would be hard to stop emitting the warning without making that assumption, and it may not be easy to make the assumption, but still avoid the expensive masking operations. -- Mark Mitchell CodeSourcery [EMAIL PROTECTED] (650) 331-3385 x713