Incorrect multiple cases in switch do not generate compiler error

I know that this code does not work as "expected". Just a quick glance at this code, we believe that the return value should be equal to 1, but 3 will be returned as a result of execution.

// incorrect variable = 1; switch (variable) { case 1, 2: return 1; case 3, 4: return 2; default: return 3; } 

and there are several correct options for this:

 // correct 1 variable = 1; switch (variable) { case 1: case 2: return 1; case 3: case 4: return 2; default: return 3; } 

or

 // correct 2 switch (variable) { case 1: case 2: return 1; case 3: case 4: return 2; default: return 3; } 

This was partially answered in several cases in the switch:

I would like to know why an irregular form compiles without errors or even warnings (at least in the Borland C ++ compiler).

What does the compiler understand in this code?

+5
source share
6 answers

Just looking at this code, we think the return value should be 1,

I would say that an experienced C ++ developer immediately noticed that something was not right and quickly came to the conclusion that some other programmer accidentally tried to use a comma:,

but as a result of execution returns 3.

No, the code should not be compiled because the case statement is not constant

And in fact, it does not compile in any intermediate modern compiler. For example, MSVC 2013 says:

 stackoverflow.cpp(8) : error C2051: case expression not constant stackoverflow.cpp(10) : error C2051: case expression not constant 

An expression of type 1, 2 is a comma operator application, and a comma operator implies that the expression is not a compile-time constant.

At least until C ++ 11 agreed and relaxed the rules to allow compilation of adding parentheses, i.e. case (1, 2): It just won’t do what you expect.

This is partially true in several cases on the switch:

How so? This other question and answers are almost exclusively about C #, not about C ++.

I would like to know why the incorrect form compiles without errors or warnings about events (at least in the Borland C ++ compiler).

Because the compiler is too old. Better get a new one.

+8
source

My hunch is that in the first case, the compiler evaluates the comma operators to lead to code execution as follows:

 switch(variable) { case 2: return 1; case 4: return 2; default: return 3; } 

You can see above why the value 3 is returned for input 1. I suggest you familiarize yourself with the comma operator. There are some excellent SO threads related to it.

+3
source

a, b is a valid expression in both C and C ++. This means "Rate a , drop it, rate b ." The value of the expression b . So your original switch has the following meaning:

 variable = 1; switch(variable) { case 2: return 1; case 4: return 2; default: return 3; } 

For more information on the comma operator, you can read the Wikipedia article .

+3
source

An expression of the form a, b is b . This is how the comma operator works.

Ostensibly then, case 1, 2: equivalent to case 2: etc.

However, the case label must be a constant integral expression, and 1, 2 not a constant expression, since it contains a comma operator (C ++ grammar dictates that a constant expression cannot contain a comma operator). Therefore, your compiler should give an error message.

You will often see case 1: case 2: which, due to the subsequent behavior of the switch allows the execution of the next line following 1 and 2 cases.

+2
source

Do some experiment.

 #include <stdio.h> int test(int variable) { switch (variable) { case 1, 2: return 1; case 3, 4: return 2; default: return 3; } } int main(void) { int i; for (i = 1; i <= 5; i++) { printf("%d -> %d\n", i, test(i)); } return 0; } 

Compiled with Borland C ++ 5.5.1 for Win32, the output was

 1 -> 3 2 -> 1 3 -> 3 4 -> 2 5 -> 3 

This shows that 1, 2 interpreted as 2 , and 3, 4 interpreted as 4 .

+1
source

In C or C ++, comma expressions have the following rules:

  • Work from left to right.
  • The expression value for the comma is the value of the last expression.

Thus, the case 1,2: code is case 2: because the expression for the comma is 2.

0
source

Source: https://habr.com/ru/post/1235890/


All Articles