error for narrowing type in switch case with c++11?

When you compile with -std=c++11 for 32-bit targets, clang complains about narrowing types in switch cases:

$ cat t1.cpp
int foo(unsigned long x) {
  switch (x) {
  case 1: return 2;
  case -1: return 0;
  }
  return 1;
}
$ clang++ -arch i386 -c t1.cpp -std=c++0x
t1.cpp:4:8: error: case value evaluates to -1, which cannot be narrowed to type
      'unsigned long'
  case -1: return 0;
       ^
1 error generated.

The corresponding code written with if-statements does not get errors, and clang only warns if you enable -Wsign-compare:

$ cat t2.cpp
int foo(unsigned long x) {
  if (x == 1) return 2;
  else if (x == -1) return 0;
  else return 1;
}
$ clang++ -arch i386 -c t2.cpp -std=c++0x
$

There is no error when compiling for x86_64 or if you don't specify -std=c++11. I think this error was introduced recently -- Howard just changed libc++ to avoid it in svn 150082. Is this error mandated by the c++11 standard or is this something we could relax? We're seeing regressions building some code due to this error (<rdar://problem/10820369>).

This error is mandated by the C++11 standard; this is one of the four places where you are not permitted narrowing conversions in C++11 (these are: braced initializers, case values, enumerators with fixed underlying types, and non-type template arguments). We saw some compile failures due to this change too, but far fewer than were introduced by the narrowing restrictions for braced initializers.

  • Richard