Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c    |    Meh, in C you gotta define EVERYTHING    |    243,242 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 241,433 of 243,242    |
|    Thiago Adams to bart    |
|    Re: bugprone-switch-missing-default-case    |
|    23 Oct 25 14:12:31    |
   
   From: thiago.adams@gmail.com   
      
   On 10/23/2025 1:46 PM, bart wrote:   
   > On 23/10/2025 17:15, Thiago Adams wrote:   
   >> On 10/23/2025 12:06 PM, David Brown wrote:   
   >   
   >> 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,   
   >   
   > How does the compiler know whether it should be used or not?   
   >   
   > And if not, how do you stop the warning? (Of non-exhaustive checking, if   
   > there is one.)   
   >   
   >> 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;   
   >> };   
   >>   
   >> }   
   >>   
   >> Then when adding a new enumerator the programmer will have to review   
   >> this code and update to 21 if it is not used, or handle it in a new case.   
   >   
   > It sounds limited. What if part of the set of enums is conditional? Then   
   > that '20' can vary depending on some macro value.   
   >   
   > But having a hard-coded 20 is also problematical; do you have to   
   > painstakingly count maybe 200 enumerations? And then keep it maintained?   
   > What if you put in the wrong number?   
   >   
   > What if you want to temporarily comment out some of those cases, or some   
   > of the enums?   
   >   
   > There may also be muliple 'switch' statements working on the same set of   
   > enums, which may need to check a different subset.   
   >   
   > Anyway, I don't see how this helps with reporting whether a enum that   
   > should be in a 'case' label is missing, or vice versa, when it should be   
   > checked.   
   >   
   >   
   >>   
   >> This is also useful in other scenarios. For instance:   
   >>   
   >>   
   >> enum E parse_enum_e(const char* s)   
   >> {   
   >> if (strcmp(s, "A") == 0) return A;   
   >> if (strcmp(s, "B") == 0) return B;   
   >> if (strcmp(s, "C") == 0) return C;   
   >> if (strcmp(s, "D") == 0) return D;   
   >> if (strcmp(s, "E") == 0) return E;   
   >> if (strcmp(s, "F") == 0) return F;   
   >> static_assert(_Countof(enum E) == 6);   
   >>   
   >> return A;   
   >> }   
   >>   
   >> If a new enumerator is added we need to include it.   
   >   
   > Another hard-coded value! An anti-pattern I think. Most of what I said   
   > above applies here. You have N enum values, you have N checking lines,   
   > and you have that static assert on N. But what happens if you leave out   
   > a checking line, or cidentally have the D line twice then check F?   
   >   
   > What if you forget to update it to 7, or write it as 5 anyway?   
   >   
   > It looks like a weak check that also adds more opportunities for error.   
   >   
   > I think getting the number of values of an enum type has some uses: you   
   > can use to iterate over the values, when they start from zero and are   
   > consecutive.   
   >   
   > Or it can iterate over arrays indexed by the enum. And it can be used to   
   > set the bounds of such arrays. These sound more useful and more reliable   
   > than your asserts!   
      
      
   I am trying to avoid having to answer each question (but if necessary I   
   can do that)   
      
   Consider:   
      
   bool is_free(enum product product)   
   {   
    switch (procuct)   
    {   
    case combo1:   
    case combo2:   
    return true;   
    default:   
    break;   
    }   
    static_assert(_countof(enum product) == 100);   
    return false;   
   }   
      
   I have 100 products (or more), just few are free.   
   I have this function that return true is the product is free.   
      
   If I add a new product I need update this function. The new product can   
   be free or not. default: assert(false) only catches the problem in runtime.   
   How to count? You can print _countof(enum product)   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca