[cfe-dev] Question about enums with explicit enum-base
Johannes Schaub (litb)
schaub.johannes at googlemail.com
Mon May 23 09:37:08 PDT 2011
Jonathan Sauer wrote:
> Hello,
>
> it is great that clang is gaining new C++0x features so quickly! Even
> seemingly "smaller" innovations like the possibility to explicitely
> specify the underlying type of an enum make programming in C++ easier.
>
> So I was experimenting with <enum-base> and stumbled upon the following:
>
>
> enum e: unsigned int { // (A)
> //enum e: unsigned short { // (B)
> A,
> B,
> C
> };
>
> int main(int, char**)
> {
> e a = A;
> return a > 0;
> }
>
>
> With line (A) active, the code compiles with clang r131844. With line (B)
> active, it results in: "use of overloaded operator '>' is ambiguous (with
> operand types 'e' and 'int')". Followed by a long list of built-in
> operators.
>
> Now, FDIS 4.5p3 says that an enum types can be converted to its underlying
> type, in this case 'unsigned short'. Furthermore, 5.9p2 says that "the
> usual arithmetic conversions" are performed for relational operators, i.e.
> according to 5p9, for the enum above, the following is done:
>
> 1. Integral promotion to 'unsigned short' (4.5p3)
> 2. Conversion of 'unsigned short' to 'int' (5p9 item 5.4)
>
> Judging from the error I got, though, it seems that clang does not perform
> the latter step.
Integral promotions can promote your "a" to both "unsigned short" and "int",
because "unsigned short" can be further promoted to "int (assuming you are
not on a 16bit box, and have int 32bit).
5.9 is not active here, because first overload resolution is done with types
"e" and "int" against "operator>". There exist the candidate:
operator>(int, int) // viable and best
That "operator>" was added by a set described as "operator>(L, R)", where
the pair "(L, R)" is the cartesian square of all promoted arithmetic types
(see 13.6p12 and 13.6p2 in the FDIS).
That one is better than all the others. The second parameter is an exact
match, and the first parameter is a promotion. For all other candidates, the
first parameter is either equally good (again "int") but then the second
parameter is not int (hence worse), or the first parameter is worse.
I can only guess that clang doesn't consider "e -> int" a promotion. Please
file a PR. Consider this, which fails too with clang:
enum e : unsigned short { };
void f(int); // should take this
void f(long);
int main() {
e e1;
f(e1);
}
More information about the cfe-dev
mailing list