Question on -Wswitch-enum

Hello.

After switching to the clang shipped with Xcode 4.4,
new warnings appeared in my previously "warnings-free" codebase.

This is an example code:
enum Enum {
   First,
   Second,
   Third,
   Fourth
};

int func(Enum e);

int func(Enum e)
{
   switch(e)
   {
      case First:
         return 42;
      case Second:
         return 84;
      default:
         return 0;
   }
}

Compiling with -Weverything I get this warning:
prova.cpp:13:11: warning: enumeration values 'Third' and 'Fourth' not explicitly handled in switch [-Wswitch-enum]
   switch(e)

In my opinion, the presence of the default: label in the switch statement should silence this warning,
because those enumeration values are actually handled. It's not like something like this:
switch(e)
{
   case First:
      return 42;
   case Second:
      return 84;
}

where the developer could have forgotten to handle all the cases.
This warning is causing a lot of noise in my project, where i have enums with dozens of enum values and
to silence this warning I have to replicate 70 case labels in every switch statement, while silencing this warning
with -Wno-switch-enum would make it disappear also for really wrong cases like the last snippet above.

So I would like to know if this is intentional, and if so what is the rationale behind this behaviour.

Thank you,
Nicola

In clang head, your test program generates no warnings, and removing the default: case introduces one, just as you propose.

Apple's random-snapshot-from-head-some-time-in-the-past most likely contains a bug.

David

In clang head, your test program generates no warnings, and removing the default: case introduces one, just as you propose.

Apple's random-snapshot-from-head-some-time-in-the-past most likely contains a bug.

Ok, I suppose it'll get fixed in the next Xcode revision.

David

Thank you,
Nicola

-Weverything includes ALL warnings clang knows about, even ones that may seem useless for most codebases like the one you just hit. As far as I know the recommended way of handling this is explicitly blacklisting warnings you don't want with "-Weverything -Wno-switch-enum".

-Wswitch-enum is not silenced by default cases, just as documented by gcc's manual.

- Ben

-Weverything includes ALL warnings clang knows about, even ones that may seem useless for most codebases like the one you just hit. As far as I know the recommended way of handling this is explicitly blacklisting warnings you don't want with "-Weverything -Wno-switch-enum".

-Wswitch-enum is not silenced by default cases, just as documented by gcc's manual.

So, is this the current behaviour in clang's head, contrary to what David said in the last email?

If this is fully intentional I can blacklist it, but I still don't understand the rationale, beyond simple
gcc compatibility.

- Ben

Thanks,
Nicola

Sorry, I was wrong, there are two warnings:

-Wswitch does what you want.
-Wswitch-enum does the wrong thing (for GCC compatibility?).

-Weverything enables both. -Weverything -Wno-switch-enum does what you want, I believe.

David

Hello.

After switching to the clang shipped with Xcode 4.4,
new warnings appeared in my previously "warnings-free" codebase.

This is an example code:
enum Enum {
   First,
   Second,
   Third,
   Fourth
};

int func(Enum e);

int func(Enum e)
{
   switch(e)
   {
      case First:
         return 42;
      case Second:
         return 84;
      default:
         return 0;
   }
}

Compiling with -Weverything I get this warning:

Compiling with -Weverything isn't a good idea I think. It enables
warnings that aren't generally useful and warnings that aren't fully
baked. Warnings that are useful will eventually find their way into
-Wall or become enabled by default.

Nico

Sorry, I was wrong, there are two warnings:

-Wswitch does what you want.
-Wswitch-enum does the wrong thing (for GCC compatibility?).

-Weverything enables both. -Weverything -Wno-switch-enum does what you want, I believe.

Ok, this makes sense.

David

Thank you,
Nicola

So, is this the current behaviour in clang's head, contrary to what David said in the last email?

If this is fully intentional I can blacklist it, but I still don't understand the rationale, beyond simple
gcc compatibility.

Sorry, I was wrong, there are two warnings:

-Wswitch does what you want.
-Wswitch-enum does the wrong thing (for GCC compatibility?).

That's correct - both of these flag names/behaviors exist in GCC & we
provide the same behavior. Clang strives to improve on the quality of
diagnostics where possible with better heuristics, code understanding
(macro awareness, etc) but in this instance the two behaviors are
clearly specified & not just an implementation-quality issue - the
issue is just that the user is using -Wswitch-enum when you want
-Wswitch.

- David

Nicola Gigante <nicola.gigante@gmail.com> writes:

In my opinion, the presence of the default: label in the switch statement
should silence this warning, because those enumeration values are actually
handled. It's not like something like this: switch(e) { case First: return
42; case Second: return 84; }

I actually opened a bug on this behavior, it was counter-intuitive to me as
well. The resolution was that it's not always desirable to make -Weverything
compile silently. You need to add a few -Won- directives as well.

Yes, having -Weverything compile silently is nearly impossible, I already
have some -Wno-* flags in the compilation flags, but I add them carefully.
Anyway, I didn’t know about the difference between -Wswitch and -Wswitch-enum,
so It’s ok after all.

Thanks,
Nicola

I actually opened a bug on this behavior, it was counter-intuitive to me as
well. The resolution was that it's not always desirable to make
-Weverything
compile silently. You need to add a few -Won- directives as well.

The behavior of -Wswitch-enum is actually very useful in some code
bases. In particular it can be nice when you use an enum for a list
of states in an embedded system. You simultaneously want to be able
to warn if you don't handle a state in a switch and you also want to
be able to have a default catch invalid states. If the default
disabled the check that all enumerated values are present as cases it
would be possible to add a new state to the enum and forget to add it
to one of the switches.

-Anton