Subject: bug#75964: Switching the Emacs build to -Wswitch-enum in src/

From: Eli Zaretskii <[email-masked]>
Date: Fri, 31 Jan 2025 14:24:17 +0200

> Date: Fri, 31 Jan 2025 12:15:04 +0000
> From: Pip Cet <[email-masked]>
> Cc: [email-masked]
> 
> "Eli Zaretskii" <[email-masked]> writes:
> 
> > What should one do if the enumeration is large and the code wants to
> > treat all but the few values the same?  This is a legitimate use case,
> 
> We have several options:
> 
> 0. do nothing, keeping bidi.o on the list of unfixed Wswitch objects,
> explaining that too many large switches are in use for the result of (1)
> to be readable
> 1. bite the bullet and apply a 184-line diff to bidi.c.
> 2. add #pragma statements in bidi.c around the five large switch
> statements, giving us the benefit of warnings for the other switch
> statements in bidi.c
> 3. turn bidi_type_t into a real integer type to avoid the warning
> 4. cast bidi_type_t to a real integer type in the switch statement.
> -1. use if() instead
> -2. use arrays instead
> -3. use arrays of function pointers instead

That might be fine when the enumeration is ours, but if it comes from
a system header file, the only practical option is 0, with 1 being a
very distant second (having a switch with many dozens of values is
hardly a good thing).

> > isn't it?  Having to spell out all of the values is quite tedious, and
> 
> I don't think the (slight) pain of having to add the case labels is the
> problem.  I'm willing to do that.

We'll then need to update that each time the library headers add more
values, so this is not something anyone of us can volunteer to do,
forever.

> The real harm is to readability, and that's really important.

Right.

> > eassume will not do what we want in this case.
> 
> Why not?

Because I'm describing the case where we actually _want_ the default
handling of an enumerated value to be something valid, whereas eassume
is for when it's invalid.

> While "default: eassume (0);" is a weird way of putting it,
> the semantics with -Werror=switch-enum are "I've handled all enumerated
> cases explicitly; if the enumeration holds an anonymous value different
> from all named values, abort in debug builds and don't generate code for
> this in optimized builds".
> 
> That applies the same no matter how large the enum is.  What am I
> missing here?

AFAIU, you are talking about the case where all the enum values were
spelled out in the switch, in which case eassume is indeed TRT.  But I
was talking about a different case.