'CASE' block doesn't need braces, or does it

Just having started coding in C I was unsure when to use {} and took the view that it couldn't be wrong to use them in excess to when writing using switch/case I used them also fro the 'case' block.
Having been told that this wasn't necessary I went back to my code and removed them from the case blocks. Result a whole string of compiler errors.
The following code has three almost identical case(9): blocks, two are commented out. Both the commented out blocks compile OK, one having {} delineators and the other the 'int incr' statement separate from the assignment of its value.
These are the compiler errors. What's going on?

Arduino: 1.6.4 (Windows 7), Board: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

Build options changed, rebuilding all

sketch_may20c.ino: In function 'void loop()':
sketch_may20c:31: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:32: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:35: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:36: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:40: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:41: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:45: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:46: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:50: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
sketch_may20c:51: error: jump to case label [-fpermissive]
sketch_may20c:14: error: crosses initialization of 'int incr'
jump to case label [-fpermissive]

char message[10];
void setup() {
  // put your setup code here, to run once:

}

void loop() {

  switch (message[0]) {


    case '9':
      Serial.println(message);
      int incr  = atoi(message);
      break;

    /*
    case '9': {
      Serial.println(message);
      int incr  = atoi(message);
      break;
    }
    */
    /*
     case '9':
       Serial.println(message);
       int incr;
       incr = atoi(message);
       break;
    */
    case 'S':
    case 's':
      Serial.println(message);
      break;
    case ('R'):
    case ('r'):
      Serial.println(message);
      break;

    case ('L'):
    case ('l'):
      Serial.println(message);
      break;

    case ('C'):
    case ('c'):
      Serial.println(message);
      break;

    case ('P'):
    case ('p'):
      break;
  }
}

If you're going to declare multiple variables with the same name ("incr") in the same scope (the "switch" code block), then I'd recommend braces for the "case"s.

AWOL:
If you're going to declare multiple variables with the same name ("incr") in the same scope (the "switch" code block), then I'd recommend braces for the "case"s.

I only declare "INCR" once in the switch code, just in the case 9 block, and in the 3rd example using

        int incr;
        incr = atoi(message);

doesn't seem to the case braces

But "incr" (C is case-sensitive) is in-scope in ALL the case blocks, but initialised only in one.
This is a potential source of bugs.

stackoverflow is a really useful resource.

Forgive the slowness of my old brain. Is the the 'scope' in this case only the 'switch' block or the main 'loop()'?. I initialised it in the case block it's used in and I don't use it anywhere else so I still don't see why declaring it on one line and initialising it on the other works (the 3rd example), but doing it on the same line doesn't, after all 'for(int i=0;.......)' is perfectly legal.

Any local variable is in scope from the point it is defined until the next closing brace.

Did you read the stackoverflow explanation?

I think the message is saying that you declare "incr" but by not taking the case label you are skipping the assignment.

So for example:

  switch (message[0]) {
    case '9':
      Serial.println(message);
      int incr  = atoi(message);
      break;
    case '8':
      incr = 8;
      break;
  }

You get the error because incr never gets the initial value on case '8'.

Safer options:

    case '9':
      {
      Serial.println(message);
      int incr  = atoi(message);
      }
      break;

That makes "incr" local scope. Or:

  int incr  = atoi(message);
  
  switch (message[0]) {


    case '9':
      Serial.println(message);
      break;
    case '8':
      // whatever;
      break;    
        
  }

Now "incr" exists inside every case label.

In your example, what is the point of the "incr" variable since you never use it?

The example was trimmed code so I could post it. The actual bit I use is

      case '9':    //numeric
         Serial.println(message);
        messptr = 0;
        int incr;
        incr = atoi(message);
        if (incr != 0) {    // only numbers so move the prior selected servo
          if (servnum > 0) {
            moveservo(servnum, last[servnum] += incr);
          }
          else {
            pstring = "No servo selected";
            Serial.println(pstring);
          }
        }
        break;

AWOL:
Any local variable is in scope from the point it is defined until the next closing brace.

Did you read the stackoverflow explanation?

No, I've just tried putting 'stackoverflow' into the search block but nothing seems relevant. could you give me a link?

To save you writing stuff like

     case '-':
      case '+':
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':

you can in some circumstances write

     case '-':
      case '+':
      case '0' ... '9':

, though it may not be portable.

No, I've just tried putting 'stackoverflow' into the search block but nothing seems relevant. could you give me a link?

I already gave you a link in reply #3

DavidI:
No, I've just tried putting 'stackoverflow' into the search block but nothing seems relevant. could you give me a link?

He gave you a link, you don't need to search for anything. Just click on it. Following his link I reached:

AWOL:
To save you writing stuff like
snip.....
you can in some circumstances write

     case '-':

case '+':
     case '0' ... '9':


, though it may not be portable.

Thanks for that, So just like pascal but pascal uses x..x not x...x (two dots not three)

Case Number of  
 1..10   : WriteLn (’Small number’);  
 11..100 : WriteLn (’Normal, medium number’);  
else  
 WriteLn (’HUGE number’);  
end;

so when I typed case '0' .. '9': and got an error I assumed you couldn't do it in C, which seems to be the case from some googling I did. Now I'm really happy! but it still seems that C won't let you do

Case C of  
 ’a’,’e’,’i’,’o’,’u’ : WriteLn (’vowel pressed’);  
 ’y’ : WriteLn (’This one depends on the language’);  
else  
  WriteLn (’Consonant pressed’);  
end;

or am I wrong again?

AWOL:
I already gave you a link in reply #3

Which I missed, sorry! going to read it now

So just like pascal but pascal uses x..x not x...x (two dots not three)

Ellipsis is always written with three dots, but Wirth is Swiss, so what does he know? :wink:

Sorry, I gave up on Pascal a long time ago.

Just read it. Now I understand. The compiler is clever enough to pick up the problem and not let me do it even though I use the variable only in that block. However, sanity check, splitting the declaration and initialisation into two separate lines

      case'1'...'9':    //numeric
         Serial.println(message);
    
        int incr;
        incr = atoi(message);

        break;

would appear to still suffer from the same problem but the compiler hasn't picked it up. So I should add the braces to limit the scope to the single 'case' right.

There is no problem any more. No initialization has been skipped. A statement has not been executed, which is different from a variable not being initialized.

If you don't add the braces then incr exists till the end of the switch statement, eg.

  switch (message[0]) {

  case'1'...'8':    //numeric
    Serial.println(message);
    int incr;
    incr = atoi(message);
    break;
  case '9':
    int incr;
    incr = atoi(message);
    Serial.println(message);
    break;

  }

Gives:

sketch_may20d.ino: In function ‘void loop()’:
sketch_may20d:18: error: redeclaration of ‘int incr’
sketch_may20d:14: error: ‘int incr’ previously declared here