[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