cpp:S3562 false positive on non-enum type switch arguments

  • Operating system: Win 10-64
  • IDE name and flavor/env: VS 2022 17.7.0
  • Version: 7.0.0.74072

Consider this code:

switch (p_length) // the input’s length as a size_t
{
case 0:
return FuncResult::Nil;

case 1:
auto rank = p_stats[0];

if (p_input_clamp)
rank = ClampTo0_1_NaNTo0(rank);

*p_rank = rank;

return FuncResult::Normal;
}

Per the documentation:

For completeness, a switch over the values of an enum must either address each value in the enum or contain a default case. switch statements that are not over enum must end with a default case.

The switch above is not processing an enum.

Hi,

Version 7.1.0.75242 was just released today. Could you please update and make sure this is still replicable?

 
Thx,
Ann

Hi, 7.1.0.75242 has the same issue.

1 Like

Hi,

Thanks for checking!

I’ve flagged this for the language experts.

 
Ann

Hi Ian,

Could you try to formulate your concern as a question? I’m not quite sure if I understand the problem at hand.

Indeed, processing an enum in a switch must either handle all possible values of that enum or—in case you process an integer value like in your example—end with a default case. Your code snippet will trigger rule S3562 and the analyzer suggests adding a default case as stated in the second point of the documentation.

Best,
Philipp

Hi Philipp,

Thanks for your reply.

My concern is: Why is rule S3562, which applies only to enumerations, act on standard integers? This creates false positives because the application of the rule doesn’t exclusively follow the rule’s definition.

As in my example, it can be useful (and create more readable code) to use a switch for lengths and other non-enum cases. Adding a default case in such scenarios would be an instance of working work the code analyzer, which is backward.

Put another way, why would a non-enum mandatorily require a default case?

Best,
Ian

Hey Ian,

Got it. Yes, working the analyzer is backward and should be avoided.

However, in the documentation for that rule, it also says that

switch statements that are not over enum must end with a default case.

If you process an integer-typed variable using a switch like in your example, the variable could potentially subsume any value in [−2,147,483,648, 2,147,483,647] assuming a 4 bytes signed integer, for instance. Since a switch is unlikely to handle all of those many cases, everything that is not handled should be addressed in a default case. We feel this is reasonable, since switch constructs are typically used to handle many cases, it is just too easy to miss one. If you, on the other hand, only have two or three cases to handle, think about using ordinary if/else (if), instead.

It seems like that for your code, you have some domain knowledge and can be sure that p_length can only be either 0 or 1. In that case, you can mark this analyzer finding as a won’t fix with a quick comment that the construct is safe in that instance. Or replace it with an ordinary if/else.

Best,
Philipp

1 Like

Hey Phillipp,

My mistake. I didn’t see the final part of the documentation. I typically use switch to test for several lengths, but I can see why a series of ifs would be better.

Thank you.

Best,
Ian

You’re most welcome. Always happy to help.

Best,
Philipp

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

Another option is to add a default with an assert, so that if the assumption about the domain knowledge breaks, you will immediately detect it.

1 Like