Thread: declare variable in case statement

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    46

    declare variable in case statement

    Just wondering why exactly this produces an error in gcc:

    Code:
    int main() {
    switch (0)
      case 0:
        int a;
    
    return 0;
    }
    Code:
    caseVariable.c: In function 'main':
    caseVariable.c:5: error: expected expression before 'int'
    Why would it not allow a variable declaration as the first line in a case statement?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Because it's the first line in a case statement. You can't introduce variables in a case statement (unless you introduce a block to introduce the variable in. So you could do this:
    Code:
    int main() {
    switch (0)
      case 0:
    {    int a;
    } /* Now the int a is safely inside a block */
    return 0;
    }
    (Edit: I know the indentation is bad, but the braces are the point.)

  3. #3
    Registered User
    Join Date
    Feb 2005
    Posts
    46

    Arrow

    Ok, but why does it allow me to declare a variable if it's the second statement? seems like an arbirary rule, but I'm sure there's some explanation

    Code:
    int main() {
    switch (0)
      case 0:
        ;
        int a;
    
    return 0;
    }

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Because in the code you posted, the variable declaration is not the second statement of the switch -- the switch doesn't have two statements. The switch ends at the semicolon, just as in
    Code:
    if (0)
        printf("This doesn't happen.\n");
        printf("This does.\n");
    the if ends at the semicolon, no matter how far I indent. If you want the switch to go farther than one statement, you'll need to have braces.

  5. #5
    Registered User
    Join Date
    Feb 2005
    Posts
    46
    Ah, Ok. I think I get it now.
    The actual code I was working on looked like this:
    Code:
    switch (val)
     case 0:
          e1;
          e2;
          ...
          en;
          break;
      case 1:
         f1;
         f2;
         ...
         fn;
         break;
       ...
       case m:
         x1;
         x2;
         ...
         xn;
         break;
    The indentation, if somewhat syntactically misleading, gets the semantics across. So basically expressions e2 - en are not considered part of the switch statement (and so on for f2-fn, x2-xn)?

    I suppose there is some difference between an if and switch statement, because the equivalent if statement is illegal :
    Code:
    if (val==0)
      e1;
    e2;
    e3;
      else if (val == 1)
        e4;
    e5;
    e6;
    ...

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Marksman View Post
    Ah, Ok. I think I get it now.
    The actual code I was working on looked like this:
    Code:
    switch (val)
     case 0:
          e1;
          e2;
          ...
          en;
          break;
      case 1:
         f1;
         f2;
         ...
         fn;
         break;
       ...
       case m:
         x1;
         x2;
         ...
         xn;
         break;
    The indentation, if somewhat syntactically misleading, gets the semantics across. So basically expressions e2 - en are not considered part of the switch statement (and so on for f2-fn, x2-xn)?
    This is also illegal; the switch would end after e1, which means that case 1, ..., m isn't in the switch either, and you can't have a case statement outside of a switch.

  7. #7
    Registered User
    Join Date
    Feb 2005
    Posts
    46
    Argh! I forgot the braces around the switch statement in all of my examples...

    Code:
    switch (val)
    {
     case 0:
          e1;
          e2;
          ...
          en;
          break;
      case 1:
         f1;
         f2;
         ...
         fn;
         break;
       ...
       case m:
         x1;
         x2;
         ...
         xn;
         break;
    }
    That's what I meant to write.
    Now the indentation is syntactically misleading because e2-en are not part of the first case technically right? (although semantically they make sense because the execution will continue from where the case left off).

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Now, e1 through en are part of case 0, and f1 through fn are part of case 1, and x1 through xn are part of case m.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Alright, I must be getting a little weird late at night. Sorry

    I can't get the compiler to complain when the int declaration is the second thing after a label, only the first -- probably because it is legal after all there. Looking at the standard, a case label must be followed by a statement -- it can be a compound statement in braces, but it must be a statement. After that declarations are allowed (in C99, but not C89), it would seem. Note that if you initialize in the declaration and that case is skipped, the variable is still in scope but it is not initialized, which makes things fun.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Tabstop: Go to bed or drink some coffee or something...
    There is no need to put braces around the code in the case-statement. You do need braces around the case-labels (at least if you want to have more than one case-label).

    This is probably a case of C vs. C++ (or C89 vs. C99). In C89, you can not declare a variable in the middle of a statement. Since there is a case-label between the brace after switch and the variable declaration, a C89 compiler will complain. C99 and C++ allows variables to be declared just about anywhere - however, declaring them inside case-labels can cause problems still, because you can have situations where the variable construction gets skipped, e.g
    Code:
    switch(x)
    {
        case 0:
         ...
            break;
        case 1:
            int y = 0;
            .... 
            break;
         case 2:
            ... 
            y++;
    Now, if the first thing that happens is that x is 2, the int y = 0 statement got skipped, and that will confuse things. I think the compiler will ALLOW you to compile that, but results is undefined. I may be wrong and it's an error.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Intel syntax on MinGW ?
    By TmX in forum Tech Board
    Replies: 2
    Last Post: 01-06-2007, 09:44 AM
  2. char copy
    By variable in forum C Programming
    Replies: 8
    Last Post: 02-06-2005, 10:18 PM
  3. case statement wrong?
    By Swaine777 in forum C++ Programming
    Replies: 4
    Last Post: 06-29-2003, 06:46 PM
  4. Variable Allocation in a simple operating system
    By awkeller in forum C Programming
    Replies: 1
    Last Post: 12-08-2001, 02:26 PM
  5. Uh-oh! I am having a major switch problem!
    By goodn in forum C Programming
    Replies: 4
    Last Post: 11-01-2001, 04:49 PM