Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type cast failed in switch for enum with restricted storage

SSCCE:

enum class confirm {yes};

struct item
{
  confirm s:4; // (1) limiting storage size required
};

int main()
{
  item itm;

  itm.s = confirm::yes; // (2) OK

  switch (itm.s)
  {
    case confirm::yes: // (3) Failure, need static data cast here?
      break;
  }
}

produces error:

In function ‘int main()’:
error: could not convert ‘yes’ from ‘confirm’ to ‘int’
 case confirm::yes:
               ^

while compiling with g++ but compiled fine by clang++. Why assignment marked by (2) possible but case clause marked by (3) not?

Warning about too small storage is of offtopic

like image 892
dyomas Avatar asked Oct 31 '22 20:10

dyomas


1 Answers

This looks like a gcc bug, we can see this works in the latest gcc version:

From the draft C++11 standard section 6.4.2 [stmt.switch]:

The condition shall be of integral type, enumeration type, or of a class type for which a single non-explicit conversion function to integral or enumeration type exists (12.3). [...] Integral promotions are performed. Any statement within the switch statement can be labeled with one or more case labels as follows:

case constant-expression :

where the constant-expression shall be a converted constant expression (5.19) of the promoted type of the switch condition.

converted constant expression is covered in section 5.19 which says:

[...]A converted constant expression of type T is a literal constant expression, implicitly converted to type T, where the implicit conversion (if any) is permitted in a literal constant expression and the implicit conversion sequence contains only user-defined conversions, lvalue-to-rvalue conversions (4.1), integral promotions (4.5), and integral conversions (4.7) other than narrowing conversions (8.5.4). [ Note: such expressions may be used as case expressions (6.4.2), as enumerator initializers if the underlying type is fixed (7.2), and as integral or enumeration non-type template arguments (14.3). —end note ] [...]

Perhaps this is related to defect report 1767: Scoped enumeration in a switch statement. So perhaps it was forcing a promotion to int and then the comparison in the case would fail.

like image 81
Shafik Yaghmour Avatar answered Nov 08 '22 05:11

Shafik Yaghmour