* enumeration value ... not handled in switch
@ 2001-09-24 1:04 Schirmer, Hartmut
2001-09-26 6:27 ` Joerg Faschingbauer
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Schirmer, Hartmut @ 2001-09-24 1:04 UTC (permalink / raw)
To: 'gcc@gcc.gnu.org'; +Cc: 'hartmut.schirmer@arcormail.de'
Hi,
is there any way to tell GCC to warn about unhandled
enum values in switch-case statements even if a default
case is present?
Currently I have to do ugly things like
flag = 0;
switch ( e )
{
case e1: flag = 1; break;
case e2: flag = 1; break;
}
if ( !flag )
{
// default case
}
to get both, the default case and the warning.
Adding an attribute to default: would be ok in this case.
Thanks,
Hartmut
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: enumeration value ... not handled in switch
2001-09-24 1:04 enumeration value ... not handled in switch Schirmer, Hartmut
@ 2001-09-26 6:27 ` Joerg Faschingbauer
2005-01-11 6:08 ` Daniel Brockman
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Joerg Faschingbauer @ 2001-09-26 6:27 UTC (permalink / raw)
To: SchirmerH; +Cc: gcc, hartmut.schirmer
From: "Schirmer, Hartmut" <SchirmerH@Innovative-Systems.de>
Subject: enumeration value ... not handled in switch
Date: Mon, 24 Sep 2001 10:06:21 +0200
> Hi,
>
> is there any way to tell GCC to warn about unhandled
> enum values in switch-case statements even if a default
> case is present?
>
> Currently I have to do ugly things like
>
> flag = 0;
> switch ( e )
> {
> case e1: flag = 1; break;
> case e2: flag = 1; break;
> }
> if ( !flag )
> {
> // default case
> }
>
> to get both, the default case and the warning.
>
> Adding an attribute to default: would be ok in this case.
This is bug #3780. I'll be cleaning up my patch a bit (although it
won't become less dirty by doing so :-) and submit it. (This won't
happen before two weeks, though.)
Joerg
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: enumeration value ... not handled in switch
2001-09-24 1:04 enumeration value ... not handled in switch Schirmer, Hartmut
2001-09-26 6:27 ` Joerg Faschingbauer
@ 2005-01-11 6:08 ` Daniel Brockman
2005-01-11 8:20 ` Daniel Brockman
2005-01-11 14:28 ` hartmut.schirmer
[not found] ` <17455984.1105449856020.JavaMail.ngmail@webmail-05.arcor-online.net>
3 siblings, 1 reply; 8+ messages in thread
From: Daniel Brockman @ 2005-01-11 6:08 UTC (permalink / raw)
To: gcc; +Cc: hartmut.schirmer
At 2001-09-26, Joerg Faschingbauer writes:
> From: "Schirmer, Hartmut" <SchirmerH@Innovative-Systems.de>
> Subject: enumeration value ... not handled in switch
> Date: Mon, 24 Sep 2001 10:06:21 +0200
>
> > Hi,
> >
> > is there any way to tell GCC to warn about unhandled
> > enum values in switch-case statements even if a default
> > case is present?
> >
> > Currently I have to do ugly things like
> >
> > flag = 0;
> > switch ( e )
> > {
> > case e1: flag = 1; break;
> > case e2: flag = 1; break;
> > }
> > if ( !flag )
> > {
> > // default case
> > }
> >
> > to get both, the default case and the warning.
> >
> > Adding an attribute to default: would be ok in this case.
>
> This is bug #3780. I'll be cleaning up my patch a bit (although it
> won't become less dirty by doing so :-) and submit it. (This won't
> happen before two weeks, though.)
(The original message is archived [1].)
Bug #3780 [2] doesn't seem to adress the issue brought up by Hartmut,
namely that adding a default case to a switch statement has the
sometimes-unfortunate side effect of turning off the warning about
unhandled enumeration values.
As it seems, this problem cannot be solved without adding an attribute
that declares a default case to be exceptional.
Consider the following code:
struct fruit
{
enum { APPLE, MELON, ORANGE } type;
...
} fruit;
...
switch (fruit.type)
{
case APPLE:
...; break;
case MELON:
...; break;
case ORANGE:
...; break;
}
Here, as soon as another value is added to the enum, gcc will warn
about the switch statement not handling it.
But what if `fruit_type' is neither `APPLE' nor `ORANGE'? The fact
that this is an impossible situation implies that when it *does*
occur, the program is in an undefined state. Thus, it should fail as
quickly and noisily as possible:
switch (fruit.type)
{
case APPLE:
...; break;
case MELON:
...; break;
case ORANGE:
...; break;
default:
abort ();
}
However, adding this guard prevents gcc from warning about unhandled
enumeration values.
The problem is that gcc cannot distinguish default cases intended to
detect impossible situations from those intended as catch-alls for
unspecified but valid enumeration values, such as this one:
switch (fruit.type)
{
case APPLE:
handle_apple (&fruit);
break;
default:
handle_other_fruit (&fruit);
}
Here, the impossible situations are deferred to `handle_other_fruit'.
Ideally, C would allow both kinds of default cases simultaneously when
switching on enums. For example, why not use the `extern' keyword?
switch (fruit.type)
{
case APPLE:
handle_apple (&fruit);
break;
default:
handle_other_fruit (&fruit);
break;
extern:
abort ();
}
Really, we don't want to do that, and it is not what I am proposing.
But the above syntax is simple syntactic sugar for the following:
switch (fruit.type)
{
case APPLE:
handle_apple (&fruit);
break;
case MELON:
case ORANGE:
handle_other_fruit (&fruit);
break;
default:
abort ();
}
The only missing piece here is being able to declare that the default
case is intended to handle *exceptional* cases only:
switch (fruit.type)
{
case APPLE:
handle_apple (&fruit);
break;
case MELON:
case ORANGE:
handle_other_fruit (&fruit);
break;
default __attribute__ ((exceptional)):
abort ();
}
The meaning of the `exceptional' attribute is simple: Any default
case with this attribute does not in itself prevent warnings about
unanticipated enumeration values.
This change would stop people from being forced to artificially choose
between run-time sanity and compile-time helpfulness.
Thanks,
--
Daniel Brockman <daniel@brockman.se>
[1] http://gcc.gnu.org/ml/gcc/2001-09/msg01034.html
[2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3780
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: enumeration value ... not handled in switch
2005-01-11 6:08 ` Daniel Brockman
@ 2005-01-11 8:20 ` Daniel Brockman
0 siblings, 0 replies; 8+ messages in thread
From: Daniel Brockman @ 2005-01-11 8:20 UTC (permalink / raw)
To: gcc
Daniel Brockman <daniel@brockman.se> writes:
> Consider the following code:
>
> struct fruit
> {
> enum { APPLE, MELON, ORANGE } type;
> ...
> } fruit;
>
> ...
>
> switch (fruit.type)
> {
> case APPLE:
> ...; break;
> case MELON:
> ...; break;
> case ORANGE:
> ...; break;
> }
>
> Here, as soon as another value is added to the enum, gcc will warn
> about the switch statement not handling it.
>
> But what if `fruit_type' is neither `APPLE' nor `ORANGE'?
What I really meant to say here was the following:
But what if `fruit_type' is neither `APPLE', `MELON', nor `ORANGE'?
Apologies,
--
Daniel Brockman <daniel@brockman.se>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: enumeration value ... not handled in switch
2001-09-24 1:04 enumeration value ... not handled in switch Schirmer, Hartmut
2001-09-26 6:27 ` Joerg Faschingbauer
2005-01-11 6:08 ` Daniel Brockman
@ 2005-01-11 14:28 ` hartmut.schirmer
[not found] ` <17455984.1105449856020.JavaMail.ngmail@webmail-05.arcor-online.net>
3 siblings, 0 replies; 8+ messages in thread
From: hartmut.schirmer @ 2005-01-11 14:28 UTC (permalink / raw)
To: gcc
Hi,
[...]
> As it seems, this problem cannot be solved without adding an attribute
> that declares a default case to be exceptional.
>
> Consider the following code:
>
> struct fruit
> {
> enum { APPLE, MELON, ORANGE } type;
> ...
> } fruit;
[...]
Adding another fruit BANANA
> [...] should fail as
> quickly and noisily as possible:
>
> switch (fruit.type)
> {
> case APPLE:
> ...; break;
> case MELON:
> ...; break;
> case ORANGE:
> ...; break;
> default:
> abort ();
> }
This may produce a warning like
enum value 'BANANA' triggers noreturn function 'abort' in switch
Creating something like __builtin_warning()
switch (fruit.type)
{
case APPLE:
...; break;
case MELON:
...; break;
case ORANGE:
...; break;
default:
__builtin_warning();
}
could trigger a similar warning without changing the control flow.
Hartmut
Arcor-DSL: die echte Flatrate für alle Bandbreiten. Jetzt ohne Einrichtungspreis
einsteigen oder wechseln. Arcor-DSL ist in vielen Anschlussgebieten verfügbar.
http://www.arcor.de/home/redir.php/emf-dsl-1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Aw: Re: enumeration value ... not handled in switch
[not found] ` <17455984.1105449856020.JavaMail.ngmail@webmail-05.arcor-online.net>
@ 2005-01-11 17:00 ` Daniel Brockman
0 siblings, 0 replies; 8+ messages in thread
From: Daniel Brockman @ 2005-01-11 17:00 UTC (permalink / raw)
To: hartmut.schirmer; +Cc: gcc
hartmut.schirmer@arcormail.de writes:
> Hi,
>
> [...]
>> As it seems, this problem cannot be solved without adding an attribute
>> that declares a default case to be exceptional.
>>
>> Consider the following code:
>>
>> struct fruit
>> {
>> enum { APPLE, MELON, ORANGE } type;
>> ...
>> } fruit;
> [...]
>
> Adding another fruit BANANA
>
>> [...] should fail as
>> quickly and noisily as possible:
>>
>> switch (fruit.type)
>> {
>> case APPLE:
>> ...; break;
>> case MELON:
>> ...; break;
>> case ORANGE:
>> ...; break;
>> default:
>> abort ();
>> }
>
> This may produce a warning like
> enum value 'BANANA' triggers noreturn function 'abort' in switch
I don't see how triggering noreturn functions in a switch in itself
warrants a warning. I have lots of code that looks like this:
void
eat_small_fruit (struct fruit *fruit)
{
switch (fruit.type)
{
case APPLE:
...; break;
case MELON:
abort ();
case ORANGE:
...; break;
}
}
Here, passing a melon to `eat_small_fruit' is a programmer error,
because a melon is not considered to be a small fruit.
> Creating something like __builtin_warning()
>
> switch (fruit.type)
> {
> case APPLE:
> ...; break;
> case MELON:
> ...; break;
> case ORANGE:
> ...; break;
> default:
> __builtin_warning();
> }
>
> could trigger a similar warning without changing the control flow.
That suffers the same problem. Should this trigger a warning?
void
eat_small_fruit (struct fruit *fruit)
{
switch (fruit.type)
{
case APPLE:
...; break;
case MELON:
__builtin_warning ();
case ORANGE:
...; break;
}
}
Regards,
--
Daniel Brockman <daniel@brockman.se>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: enumeration value ... not handled in switch
2001-09-26 9:03 Schirmer, Hartmut
@ 2001-09-26 10:55 ` Joerg Faschingbauer
0 siblings, 0 replies; 8+ messages in thread
From: Joerg Faschingbauer @ 2001-09-26 10:55 UTC (permalink / raw)
To: SchirmerH; +Cc: jfasch, gcc
From: "Schirmer, Hartmut" <SchirmerH@Innovative-Systems.de>
Subject: RE: enumeration value ... not handled in switch
Date: Wed, 26 Sep 2001 18:05:02 +0200
> Hi,
>
> > This is bug #3780. I'll be cleaning up my patch a bit (although it
> > won't become less dirty by doing so :-) and submit it. (This won't
> > happen before two weeks, though.)
>
> not really the same problem.
>
> In my C code (not C++) I have
>
> enum { A, B, C } x;
>
> switch (x)
> {
> case A:
> case B:
> case C:
> break;
> default:
> // strange
> abort();
> }
>
> The default case is for runtime safty. The variable x may be in an
> illegal state (not initialized, corupted, ...)
>
> If I later add a D to the enum I won't get a warning because of
> the default case. Changing the code to
>
> switch (x)
> {
> case A:
> case B:
> case C:
> break;
> default attribute(silent):
> // strange
> abort();
> }
>
> enables the compile time analysis so I don't have to wait for
> a runtime error.
I obviously misunderstood.
Joerg
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: enumeration value ... not handled in switch
@ 2001-09-26 9:03 Schirmer, Hartmut
2001-09-26 10:55 ` Joerg Faschingbauer
0 siblings, 1 reply; 8+ messages in thread
From: Schirmer, Hartmut @ 2001-09-26 9:03 UTC (permalink / raw)
To: 'Joerg Faschingbauer'; +Cc: 'gcc@gcc.gnu.org'
Hi,
> This is bug #3780. I'll be cleaning up my patch a bit (although it
> won't become less dirty by doing so :-) and submit it. (This won't
> happen before two weeks, though.)
not really the same problem.
In my C code (not C++) I have
enum { A, B, C } x;
switch (x)
{
case A:
case B:
case C:
break;
default:
// strange
abort();
}
The default case is for runtime safty. The variable x may be in an
illegal state (not initialized, corupted, ...)
If I later add a D to the enum I won't get a warning because of
the default case. Changing the code to
switch (x)
{
case A:
case B:
case C:
break;
default attribute(silent):
// strange
abort();
}
enables the compile time analysis so I don't have to wait for
a runtime error.
Hartmut
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2005-01-11 16:04 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-24 1:04 enumeration value ... not handled in switch Schirmer, Hartmut
2001-09-26 6:27 ` Joerg Faschingbauer
2005-01-11 6:08 ` Daniel Brockman
2005-01-11 8:20 ` Daniel Brockman
2005-01-11 14:28 ` hartmut.schirmer
[not found] ` <17455984.1105449856020.JavaMail.ngmail@webmail-05.arcor-online.net>
2005-01-11 17:00 ` Aw: " Daniel Brockman
2001-09-26 9:03 Schirmer, Hartmut
2001-09-26 10:55 ` Joerg Faschingbauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).