Error: Jump to Case Label in Switch Statement

Error: Jump to case label in switch statement

The problem is that variables declared in one case are still visible in the subsequent cases unless an explicit { } block is used, but they will not be initialized because the initialization code belongs to another case.

In the following code, if foo equals 1, everything is ok, but if it equals 2, we'll accidentally use the i variable which does exist but probably contains garbage.

switch(foo) {
case 1:
int i = 42; // i exists all the way to the end of the switch
dostuff(i);
break;
case 2:
dostuff(i*2); // i is *also* in scope here, but is not initialized!
}

Wrapping the case in an explicit block solves the problem:

switch(foo) {
case 1:
{
int i = 42; // i only exists within the { }
dostuff(i);
break;
}
case 2:
dostuff(123); // Now you cannot use i accidentally
}

Edit

To further elaborate, switch statements are just a particularly fancy kind of a goto. Here's an analoguous piece of code exhibiting the same issue but using a goto instead of a switch:

int main() {
if(rand() % 2) // Toss a coin
goto end;

int i = 42;

end:
// We either skipped the declaration of i or not,
// but either way the variable i exists here, because
// variable scopes are resolved at compile time.
// Whether the *initialization* code was run, though,
// depends on whether rand returned 0 or 1.
std::cout << i;
}

What is causing this: Cannot jump from switch statement to this case label

C is not Swift. You'll be happier if you structure your switch statements using curly braces round all of the cases interiors, like this:

switch (tag) {
case 1: { // curly braces
// ...
break;
}
case 2: { // curly braces
// ...
break;
}
case 3: { // curly braces
// ...
break;
}
}

The extra level of curly braces allows you to do things you can't do otherwise.

Jump to case label error when using vectors inside switch statement.

Add another scope inside the case:

switch(n) 
{
case 1:
{
std::vector<int> foo;
// ...
break;
}
case 2:
// ...
default:
// ...
}

The extra scope constrains the lifetime of the vector object. Without it, a jump to case 2 would skip over the initialization of the object, which would nonetheless have to be destroyed later, and this is illegal.

jump to case label crosses initialization of 'std::unique_lock std::mutex '


switch(opn_type) {
case 1: {
std::unique_lock<std::mutex> ul(m);
// do processing and add to queue
cv.notify_one();
ul.unlock();

} break;

default:
break;
}

case labels don't end variable lifetime, so ul exists and is destroyed after default: but only initialized within case 1:.

Put it in a block.

switch(opn_type) {
case 1: {
std::unique_lock<std::mutex> ul(m);
// do processing and add to queue
cv.notify_one();
} break;

default:
break;
}

the .unlock() does nothing, as the scope is ending right there. In this version I removed it.

Note that I find mixing threading primitives with other code to be dangerous.

template<class T>
struct threadsafe_queue {
T pop() {
auto l = lock();
cv.wait(lk, [&]{return !queue.empty();});
T retval = queue.front();
queue.pop_front();
return retval;
}
void push( T in ) {
auto l = lock(m);
queue.push_back(std::move(in));
cv.notify_one();
}
std::deque<T> pop_all() {
auto l = lock();
return std::move(queue);
}
private:
mutable std::mutex m;
std::condition_variable cv;
std::deque<T> queue;
std::unique_lock<std::mutex> lock() const {
return std::unique_lock<std::mutex>(m);
}
};

adding "try_pop", "try_pop_for" etc is an exercise.

Having an error case label does not reduce to an integer constant using switch in C

According to the C Standard (6.8.4.2 The switch statement)

3 The expression of each case label shall be an integer constant
expression and no two of the case constant expressions in the same
switch statement shall have the same value after conversion
. There
may be at most one default label in a switch statement. (Any enclosed
switch statement may have a default label or case constant expressions
with values that duplicate case constant expressions in the enclosing
switch statement.)

and (6.6 Constant expressions)

6 An integer constant expression117) shall have integer type and shall
only have operands that are integer constants, enumeration constants,
character constants, sizeof expressions whose results are integer
constants, and floating constants that are the immediate operands of
casts. Cast operators in an integer constant expression shall only
convert arithmetic types to integer types, except as part of an
operand to the sizeof operator.

In this switch statement from the first program

switch (guess)
{
case guess < x:
printf("High \n");
scanf("%d", &guess);
break;
case guess > x:
printf("Low \n");
scanf("%d", &guess);
break;
case guess == x:
printf("Exact");
break;
default:
break;
}

case labels are not integer constant expressions. So the compiler issues an error.

Instead you could write using the switch statement the following way. Pay attention to that you need to use a loop. Otherwise the user will have only one attempt.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main( void )
{
int success = 0;
srand( ( unsigned )time( NULL ) );
int x = rand() % 100;

do
{
int guess;
printf("Guessing value: \n");

scanf( "%d", &guess );

success = ( x < guess ) - ( guess < x );

switch ( success )
{
case 1:
printf("High \n");
break;
case -1:
printf("Low \n");
break;
case 0:
printf("Exact");
break;
}
} while ( success != 0 );

return 0;
}

You could also to introduce named constant for values 0, -1, and 1 as for example

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main( void )
{
enum { Exact = 0, Low = -1, High = 1 };

srand( ( unsigned )time( NULL ) );
int x = rand() % 100;

int success = Exact;

do
{
int guess;
printf( "Guessing value: \n" );

scanf( "%d", &guess );

success = ( x < guess ) - ( guess < x );

switch ( success )
{
case High:
printf("High \n");
break;
case Low:
printf("Low \n");
break;
case Exact:
printf("Exact");
break;
}
} while ( success != Exact );

return 0;
}

Having same expression inside case in switch statement

Both expressions 'a' && 1 and 'b' && 1 have the value 1.

Therefore your code is strictly equivalent to this:

...
switch(c){
case 1: printf("Hello");
case 1: printf("hey");
break;
default : printf("Goodbye");
}
}
...

Hence the error message because two or more case labels cannot have the same value. The C language does not allow this.



Related Topics



Leave a reply



Submit