Re: C99 mixed declarations / switch case / weird syntax behavior

Discussion in 'C Programming' started by Michael Mair, Jun 13, 2005.

  1. Michael Mair

    Michael Mair Guest

    This is a C thing, not a compiler problem:

    Xpost and f'up2 comp.lang.c

    Didier Verna wrote:
    > Hi !
    >
    > GCC (3.3.6) has a weird syntax behavior WRT C99 mixed declarations in switch /
    > case statements (sometimes it requires a brace to open a block, sometimes
    > not). This is demonstrated by the following example:
    >
    > ------------------------------------------------------------------------
    >
    > typedef enum
    > {
    > CASE_1,
    > CASE_2
    > } enum_e;
    >
    > void foo ()
    > {
    > enum_e case_1 = CASE_1;
    >
    > switch (case_1)
    > {
    > case CASE_1:
    > /* int i; */ /* This leads to a parse error. */
    > foo ();
    > break;
    > case CASE_2:
    > foo ();
    > int i; /* This is OK. */
    > foo ();
    > break;
    > }
    > }
    >
    > ------------------------------------------------------------------------
    >
    > Any comment on this ?


    Yep; a case-label may precede only a statement (C99, 6.8.1#1).
    A statement in turn is either a labeled statement (i.e. case/default or
    a label for goto followed by a statement), or a
    selection/jump/iteration/expression statement, or a compound statement
    (i.e. { block-item-list } where a block-item may be a declaration or a
    statement) -- but no declaration.

    Notes:
    -You cannot do
    if(foo == 42)
    int i;
    either.
    -The fact that "int i;" is allowed _after_ foo(); is due to the
    fact that switch(case_1) is followed by a compound statement.
    The block-items preceded by a label have to be statements, the
    others can be either statements or declarations.
    -This of course means that
    switch (a)
    {
    int i;
    case 1:
    i=47;
    bar();
    break;
    case 2;
    for (i=0; i<3; i++)
    bar();
    break;
    }
    is possible (but an initializer of i has no effect whatsoever, and a
    forgotten initialisation of i for a certain case leads to undefined
    behaviour). Furthermore,
    case 1:
    foo();
    int i;
    break;
    case 2:
    bar();
    int i;
    break;
    means that you have a re-declaration of i after bar().
    - A further educative example is Duff's device:
    http://www.lysator.liu.se/c/duffs-device.html

    So, yes, gcc is right in _this_ case. Note, however, that gcc is
    not fully C99 compliant.

    The c.l.c people probably will find lots to correct or expand on
    but this should get you started.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Jun 13, 2005
    #1
    1. Advertising

  2. Michael Mair

    S.Tobias Guest

    In comp.lang.c Michael Mair <> wrote:
    > Didier Verna wrote:


    > > switch (case_1)
    > > {
    > > case CASE_1:
    > > /* int i; */ /* This leads to a parse error. */
    > > foo ();
    > > break;
    > > case CASE_2:
    > > foo ();
    > > int i; /* This is OK. */
    > > foo ();
    > > break;
    > > }


    > Yep; a case-label may precede only a statement (C99, 6.8.1#1).

    [sniped what a statement was]

    > Notes:

    [snipped notes]

    There's a similar pit-fall in situations like this:

    switch (something)
    {
    case 1:
    /*code*/
    default:
    }

    void f()
    {
    if (do_nothing)
    goto end;
    /* do_something code */
    end:
    }

    All require and empty statement (";") to be fixed.
    For example, OP's code could be fixed by:

    case CASE_1:
    ;
    int i; /* Now should be correct. */
    foo ();
    break;

    [If someone asked why I put "default:" at the end, where no code
    follows, the answer is simply to silence warnings. ]

    --
    Stan Tobias
    mailx `echo LID | sed s/[[:upper:]]//g`
     
    S.Tobias, Jun 14, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neil Zanella

    C99: variable declarations inside switch statements

    Neil Zanella, Oct 27, 2003, in forum: C Programming
    Replies:
    5
    Views:
    499
    Christian Bau
    Oct 28, 2003
  2. Replies:
    3
    Views:
    3,700
    Chris Torek
    Feb 20, 2006
  3. Chad
    Replies:
    7
    Views:
    330
    Boltar
    Jan 5, 2007
  4. Replies:
    9
    Views:
    369
    shish
    May 2, 2007
  5. Mukesh
    Replies:
    4
    Views:
    633
    Paul N
    Mar 26, 2010
Loading...

Share This Page