Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #394687

Re: bugprone-switch-missing-default-case

From David Brown <david.brown@hesbynett.no>
Newsgroups comp.lang.c
Subject Re: bugprone-switch-missing-default-case
Date 2025-10-23 22:40 +0200
Organization A noiseless patient Spider
Message-ID <10de3sh$24ftv$1@dont-email.me> (permalink)
References (4 earlier) <20251022111414.630@kylheku.com> <10dckhj$1dnn6$2@dont-email.me> <10dd215$3totj$2@dont-email.me> <10ddg8q$1r5el$1@dont-email.me> <10ddkb2$1tadp$1@dont-email.me>

Show all headers | View raw


On 23/10/2025 18:15, Thiago Adams wrote:
> On 10/23/2025 12:06 PM, David Brown wrote:
>> On 23/10/2025 13:03, Thiago Adams wrote:
>>> On 10/23/2025 4:12 AM, David Brown wrote:
>>>> On 22/10/2025 20:22, Kaz Kylheku wrote:
>>>>> On 2025-10-22, Thiago Adams <thiago.adams@gmail.com> wrote:
>>>>>> On 10/22/2025 8:44 AM, Richard Harnden wrote:
>>>>>> ....
>>>>>>>> Your program fragment is well defined.
>>>>>>>>
>>>>>>>> What the poster certainly tried to express was that in case you
>>>>>>>> haven't implemented a complete list of all possible cases and
>>>>>>>> also not provided a 'default' to catch all non-specified cases,
>>>>>>>> then you might get in troubles with your program, probably by
>>>>>>>> possible oversights, future extensions, new data, and whatnot.
>>>>>>>>
>>>>>>>> Personally I have the habit to always define a default branch,
>>>>>>>> and even if that default is impossible to reach you'll find an
>>>>>>>> error message (like "internal error with unexpected value...")
>>>>>>>> generated at that place.
>>>>>>>>
>>>>>>> Use an enum, and the compiler will warn you ...
>>>>>>>
>>>>>>> $ cat x.c
>>>>>>> #include <stdio.h>
>>>>>>>
>>>>>>> enum x {A, B, C};
>>>>>>>
>>>>>>> int main(void)
>>>>>>> {
>>>>>>>       enum x x = C;
>>>>>>>
>>>>>>>       switch (x)
>>>>>>>       {
>>>>>>>           case A:
>>>>>>>               printf("A\n");
>>>>>>>               break;
>>>>>>>
>>>>>>>           case B:
>>>>>>>               printf("B\n");
>>>>>>>               break;
>>>>>>>       }
>>>>>>>
>>>>>>>       return 0;
>>>>>>> }
>>>>>>>
>>>>>>> $ gcc -Wall x.c
>>>>>>> x.c: In function ‘main’:
>>>>>>> x.c:9:9: warning: enumeration value ‘C’ not handled in switch [- 
>>>>>>> Wswitch]
>>>>>>>       9 |         switch (x)
>>>>>>>         |         ^~~~~~
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> The problem with this GCC approach is when there are many enumerators
>>>>>> but only a few are used.
>>>>>
>>>>> The problem with the C and GCC approach is that there is no
>>>>> one-size-fits all solution.
>>>>>
>>>>> Some switches are intended to be exhaustive, such that
>>>>> missing a case is a bug.
>>>>>
>>>>> Some are not.
>>>>>
>>>>> You need an "eswitch" for the exhaustively handled enumerations,  and
>>>>> switch for the others.
>>>>>
>>>>> GCC can turn on diagnostics over ranges of a file with pragma
>>>>> and there is also _Pragram, but it's all too clumsy.
>>>>>
>>>>
>>>> The gcc approach works fine in almost all situations - use "- 
>>>> Wswitch=error", and add a default case if your switch is not meant 
>>>> to handle all enumeration values.  If the default should do nothing, 
>>>> it's just "default: // Not all cases need handling".  If the default 
>>>> should never happen, "default: __builtin_unreachable();" or 
>>>> "default: __builtin_trap();" might be appropriate.
>>>>
>>>>
>>>>
>>>
>>> But then instead a compiler time error (like I suggest) you leave it 
>>> for runtime.
>>>
>>>
>>
>> As I said - use "-Wswitch=error".  That gives you a compile-time error 
>> - not merely a warning, as you had suggested.  But /if/ your switch is 
>> not meant to handle all cases, which was what Kaz was complaining 
>> about, then you add a default case.  I agree with you that a compile- 
>> time error is best when possible, which is why that was my suggestion.
>>
>>
>>
> 
> 
> I think my sample is not covered by any GCC flag
> 
> 
> I will copy past it again:
> --------
> The problem with this GCC approach is when there are many enumerators 
> but only a few are used.
> 
> For instance :
> 
> enum E {A, B, C /*, ...*/, Z};
> 
> 1)
> void f(enum E e)
> {
>      switch (e)
>      {
>          //used
>          case A:
>          case B:
>           break;
> 
>          //NON USED
>          case C:
>          ...
>          case Z:
>           break;
>      };
> }
> 
> The problem with (1) is when we have too many
> non used enumerators, it is impractical to have a lot of switch cases.
> 
> One alternative is to use default for all the non used:
> 
> 2)
> void f(enum E e)
> {
>      switch (e)
>      {
>          //used
>          case A:
>          case B:
>           break;
> 
>          //NON USED (all others)
>          default:
>           break;
>      };
> }
> 
> 
> The problem with (2) is when we add a new enumerator and
> this new enumerations should be used, but there is no warning and it 
> goes accidentally for default.
> 
> 
> Solution?
> 
> In C2Y the new keyword _Countof was introduced.
> It works returns the number of elements of array. IT IS FOR ARRAY ONLY.
> 
> I did an EXTENSION in my compiler where _Countof(enum E) also returns 
> the number of enumerators.
> 
> 
> enum E2 {A, B};
> static_assert(_Countof(enum E2) == 2);
> 
> (It also could be a new keyword.
> static_assert(_EnumCount(enum E2) == 2);)
> 
> Having this we can do:
> 
> 3)
> void f(enum E e)
> {
>      switch (e)
>      {
>          //used
>          case A:
>          case B:
>           break;
> 
>          default:
>           static_assert(_EnumCount(enum E2) == 20);
>           break;
>      };
> 
> }
> 
I appreciate that enumerations in C are missing a lot of potential 
compared to enumerations in some other languages (they could be real new 
types that do not implicitly convert with "int", they could have a 
"count" feature, they could have a feature for having the identifier 
names in a const array of strings, etc.).  But none of this is at all 
hard with today's enums :

enum E1 { A, B, C, D, last_E1 = D };

  void f(enum E1 e)
  {
       switch (e)
       {
           //used
           case A:
           case B:
            break;

           default:
            static_assert(last_E1 == D);
	   // or, according to preference
            static_assert(last_E1 == 4);
            break;
       };

  }

People do this regularly.  Personally, I usually prefer to have the 
"last", "max", or "count" indicator outside the enumeration :

	enum E1 { A, B, C, D };
	static const int count_of_E1 = D;

It is not standardised, so different people use different names, but 
it's perfectly doable.

And if you want to automate it a little more and negate the possibility 
of forgetting to change the "count_of_E1" line, because automation of 
these things is nice, then I think you could easily put together an 
XMacro style solution.

In a new, different language, I'd want better enumerations with more 
features, and this kind of thing could be handled better in the 
language.  But for C, I can't see this being worth the effort for an 
extension.


Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

bugprone-switch-missing-default-case pozz <pozzugno@gmail.com> - 2025-10-22 10:56 +0200
  Re: bugprone-switch-missing-default-case Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-10-22 11:32 +0200
    Re: bugprone-switch-missing-default-case Richard Harnden <richard.nospam@gmail.invalid> - 2025-10-22 12:44 +0100
      Re: bugprone-switch-missing-default-case Thiago Adams <thiago.adams@gmail.com> - 2025-10-22 10:05 -0300
        Re: bugprone-switch-missing-default-case Kaz Kylheku <643-408-1753@kylheku.com> - 2025-10-22 18:22 +0000
          Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-23 09:12 +0200
            Re: bugprone-switch-missing-default-case Thiago Adams <thiago.adams@gmail.com> - 2025-10-23 08:03 -0300
              Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-23 17:06 +0200
                Re: bugprone-switch-missing-default-case Thiago Adams <thiago.adams@gmail.com> - 2025-10-23 13:15 -0300
                Re: bugprone-switch-missing-default-case bart <bc@freeuk.com> - 2025-10-23 17:46 +0100
                Re: bugprone-switch-missing-default-case Thiago Adams <thiago.adams@gmail.com> - 2025-10-23 14:12 -0300
                Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-23 22:40 +0200
                Re: bugprone-switch-missing-default-case scott@slp53.sl.home (Scott Lurndal) - 2025-10-23 20:51 +0000
                Re: bugprone-switch-missing-default-case Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-10-23 16:21 -0700
                Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-24 08:59 +0200
                Re: bugprone-switch-missing-default-case scott@slp53.sl.home (Scott Lurndal) - 2025-10-24 15:51 +0000
                Re: bugprone-switch-missing-default-case tTh <tth@none.invalid> - 2025-10-23 23:57 +0200
                Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-24 09:22 +0200
                Re: bugprone-switch-missing-default-case antispam@fricas.org (Waldek Hebisch) - 2025-10-23 23:23 +0000
                Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-24 09:53 +0200
      Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-22 15:41 +0200
        Re: bugprone-switch-missing-default-case Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-10-22 16:05 +0200
          Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-22 17:23 +0200
            Re: bugprone-switch-missing-default-case Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-10-23 04:54 +0200
              Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-23 09:30 +0200
            Re: bugprone-switch-missing-default-case antispam@fricas.org (Waldek Hebisch) - 2025-10-23 22:40 +0000
        Re: bugprone-switch-missing-default-case Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-10-22 12:41 -0700
          Re: bugprone-switch-missing-default-case pozz <pozzugno@gmail.com> - 2025-10-23 08:47 +0200
            Re: bugprone-switch-missing-default-case Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-10-23 16:17 -0700
              Re: bugprone-switch-missing-default-case Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-10-23 19:13 -0700
          Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-23 10:44 +0200
      Re: bugprone-switch-missing-default-case Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-10-22 15:56 +0200
        Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-22 17:25 +0200
          Re: bugprone-switch-missing-default-case Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-10-23 04:39 +0200
            Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-23 09:08 +0200
          Re: bugprone-switch-missing-default-case Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-10-23 16:31 -0700
            Re: bugprone-switch-missing-default-case David Brown <david.brown@hesbynett.no> - 2025-10-24 10:09 +0200
  Re: bugprone-switch-missing-default-case Kaz Kylheku <643-408-1753@kylheku.com> - 2025-10-22 18:13 +0000

csiph-web