public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).