User account creation filtered due to spam.

Bug 41425 - switch with enums doesn't work
Summary: switch with enums doesn't work
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.1
: P3 critical
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-09-21 12:17 UTC by André Wöbbeking
Modified: 2010-05-04 04:48 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
testcase (163 bytes, text/x-c++src)
2009-09-21 12:19 UTC, André Wöbbeking
Details

Note You need to log in before you can comment on or make changes to this bug.
Description André Wöbbeking 2009-09-21 12:17:02 UTC
If I cast an int to the enum type all values outside the enum triggers the first case-statement.

The number of enum values is important. It must be a power of 2.

This works in GCC 4.3.4.
Comment 1 André Wöbbeking 2009-09-21 12:19:29 UTC
Created attachment 18622 [details]
testcase
Comment 2 André Wöbbeking 2009-09-21 12:21:32 UTC
g++ case.cpp is sufficient to reproduce this.
Comment 3 Paolo Carlini 2009-09-21 12:41:31 UTC
As far as I can see, you are triggering undefined behavior. Per 5.2.9/7: "A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resulting enumeration value is unspecified."
Comment 4 Richard Biener 2009-09-21 12:44:29 UTC
In C++ an enum type only has the minimum number of bits that is required to
store all its values, thus 1 in your case.  So (foo)5 is a truncation.
Comment 5 André Wöbbeking 2009-09-21 12:53:58 UTC
Paolo, but std::cout << static_cast<foo>(i); prints 5, so it's not the conversion but the switch statement which is "broken".

Richard, if it's only truncation shouldn't case B be triggered?
Comment 6 Richard Biener 2009-09-21 13:08:33 UTC
Switch assembly is optimized if you handle all valid cases (which you do) into
if (i != 0)
  case B
else
  case A
Comment 7 Andreas Schwab 2009-09-21 14:25:11 UTC
(In reply to comment #3)
> As far as I can see, you are triggering undefined behavior.

There is a big difference between undefined and unspecified behaviour.  With unspecified behaviour the implementation must chose a consistent behaviour, although it does not have to document which one it choses.
Comment 8 Paolo Carlini 2009-09-21 14:45:48 UTC
Agreed, unspecified, as the actual citation says.
Comment 9 André Wöbbeking 2009-09-21 16:46:03 UTC
So it's ok to change the behavior in a minor release?
Comment 10 Richard Biener 2009-09-22 11:43:35 UTC
Yes, as part of a wrong-code fix.
Comment 11 Jason Merrill 2010-05-04 04:48:10 UTC
In G++ 4.6 the confusing optimization will only be performed with -fstrict-enums.