why does C standard allow this declaration

Discussion in 'C Programming' started by sunny, Sep 20, 2006.

  1. sunny

    sunny Guest

    Hi

    Why does C allows declaration of variable inside switch block.
    ex: foll prg does not gives "undeclared "b" error msg. but also does
    not initialize b to 20
    int a=1;
    switch(a)
    {
    int b=20;
    case 1: printf("b is %d\n",b);
    break;
    default:printf("b is %d\n",b);
    break;
    }

    this prints some garbage.
    ( yeah even though i got warning msg "unreachable code int b = 20" why
    is it declaring inside switch block but not initializing b)
    sunny, Sep 20, 2006
    #1
    1. Advertising

  2. "sunny" <> writes:

    >Why does C allows declaration of variable inside switch block.
    >ex: foll prg does not gives "undeclared "b" error msg. but also does
    >not initialize b to 20
    > int a=1;
    > switch(a)
    > {
    >int b=20;
    > case 1: printf("b is %d\n",b);
    > break;
    > default:printf("b is %d\n",b);
    > break;
    > }


    >this prints some garbage.
    >( yeah even though i got warning msg "unreachable code int b = 20" why
    >is it declaring inside switch block but not initializing b)



    Programs do not give warnings about themselves;
    different compilers may give different warnings and errors.

    You will probably be horrified by Duff's Device:

    http://www.lysator.liu.se/c/duffs-device.html#duffs-device
    http://www.catb.org/jargon/html/D/Duffs-device.html

    --
    Chris,
    Chris McDonald, Sep 20, 2006
    #2
    1. Advertising

  3. sunny

    Tejas Kokje Guest

    sunny wrote:
    > Hi
    >
    > Why does C allows declaration of variable inside switch block.
    > ex: foll prg does not gives "undeclared "b" error msg. but also does
    > not initialize b to 20
    > int a=1;
    > switch(a)
    > {
    > int b=20;
    > case 1: printf("b is %d\n",b);
    > break;
    > default:printf("b is %d\n",b);
    > break;
    > }
    >
    > this prints some garbage.
    > ( yeah even though i got warning msg "unreachable code int b = 20" why
    > is it declaring inside switch block but not initializing b)



    It depends on your compiler. I am using gcc and it throws following
    warning message

    [kokje@RocketFuel ~]$ gcc test.c -o test
    test.c: In function `main':
    test.c:7: warning: unreachable code at beginning of switch statement

    What compiler are you using ?

    Tejas Kokje
    Tejas Kokje, Sep 20, 2006
    #3
  4. sunny wrote:
    > Hi
    >
    > Why does C allows declaration of variable inside switch block.
    > ex: foll prg does not gives "undeclared "b" error msg. but also does
    > not initialize b to 20
    > int a=1;
    > switch(a)
    > {
    > int b=20;
    > case 1: printf("b is %d\n",b);
    > break;
    > default:printf("b is %d\n",b);
    > break;
    > }



    this is an unfortunate side efect of allowing declarations at the
    beginning of any block, and the switch statement requiring a block, or
    at least to be useful;

    In general it's not fair to look for extreme sense in C, it was just
    supposed to be a pragmatic, ad-hoc language for use by some genius
    coders at Bell Labs, 30+ years ago, for hecks sake!
    Ancient_Hacker, Sep 20, 2006
    #4
  5. sunny

    sunny Guest

    i am using gcc available with Cygwin

    Tejas Kokje wrote:

    > sunny wrote:
    > > Hi
    > >
    > > Why does C allows declaration of variable inside switch block.
    > > ex: foll prg does not gives "undeclared "b" error msg. but also does
    > > not initialize b to 20
    > > int a=1;
    > > switch(a)
    > > {
    > > int b=20;
    > > case 1: printf("b is %d\n",b);
    > > break;
    > > default:printf("b is %d\n",b);
    > > break;
    > > }
    > >
    > > this prints some garbage.
    > > ( yeah even though i got warning msg "unreachable code int b = 20" why
    > > is it declaring inside switch block but not initializing b)

    >
    >
    > It depends on your compiler. I am using gcc and it throws following
    > warning message
    >
    > [kokje@RocketFuel ~]$ gcc test.c -o test
    > test.c: In function `main':
    > test.c:7: warning: unreachable code at beginning of switch statement
    >
    > What compiler are you using ?
    >
    > Tejas Kokje
    sunny, Sep 20, 2006
    #5
  6. sunny

    Guest

    sunny wrote:

    > Hi
    >
    > Why does C allows declaration of variable inside switch block.


    because it allows declaration of variables inside any braced block.

    > ex: foll prg does not gives "undeclared "b" error msg. but also does
    > not initialize b to 20
    > int a=1;
    > switch(a)
    > {
    > int b=20;
    > case 1: printf("b is %d\n",b);
    > break;
    > default:printf("b is %d\n",b);
    > break;
    > }
    >
    > this prints some garbage.
    > ( yeah even though i got warning msg "unreachable code int b = 20" why
    > is it declaring inside switch block but not initializing b)


    automatic variables (of which b is an example) are initialized as if by
    an assignment (I'm talking casually here).

    So it's as if the block starts with :-
    {
    int b; /* declaration */
    b = 20; /* initialization */
    case 1: <etc>

    But in a switch statement only the operations following "case" or
    "default" are executed. Hence the variable b is declared, but not
    initialized.
    , Sep 20, 2006
    #6
  7. sunny

    jmcgill Guest

    Chris McDonald wrote:
    > You will probably be horrified by Duff's Device:


    I'm not so much horrified as puzzled by the location of the while.
    Is it the equivalent of a goto into a do loop?
    jmcgill, Sep 20, 2006
    #7
  8. sunny

    Guest

    sunny wrote:

    > Hi
    >
    > Why does C allows declaration of variable inside switch block.


    I went back to my dog-eared copy of K & R (1st edition).

    On P.203 it says "Declarations may appear at the head of [the subject
    of a switch], but initializations of automatic and register variables
    are ineffective".

    So one answer to "why?" is "because that's what K & R said".
    , Sep 20, 2006
    #8
  9. On 2006-09-20, sunny <> wrote:
    > Hi
    >
    > Why does C allows declaration of variable inside switch block.
    > ex: foll prg does not gives "undeclared "b" error msg. but also does
    > not initialize b to 20
    > int a=1;
    > switch(a)
    > {
    > int b=20;
    > case 1: printf("b is %d\n",b);
    > break;
    > default:printf("b is %d\n",b);
    > break;
    > }
    >
    > this prints some garbage.
    > ( yeah even though i got warning msg "unreachable code int b = 20" why
    > is it declaring inside switch block but not initializing b)


    As the warning message stated, the initialization is unreachable code.
    According to the specification:

    Storage is guaranteed to be reserved for a new instance of such an
    object on each normal entry into the block with which it is associated,
    or on a jump from outside the block to a labeled statement in the
    block or in an enclosed block. If any initialization is specified for
    the value stored in the object, it is performed on each normal entry,
    but not if the block is entered by a jump to a labeled statement.

    The compiler is conforming to the specification, and it is giving a
    warning about the initialization not being performed.
    A. Bolmarcich, Sep 20, 2006
    #9
  10. sunny

    Guest

    wrote:
    > sunny wrote:
    >
    > > Hi
    > >
    > > Why does C allows declaration of variable inside switch block.

    >
    > because it allows declaration of variables inside any braced block.


    Old C doesn't allow variables to be declared everywhere, right?

    > > ex: foll prg does not gives "undeclared "b" error msg. but also does
    > > not initialize b to 20
    > > int a=1;
    > > switch(a)
    > > {
    > > int b=20;
    > > case 1: printf("b is %d\n",b);
    > > break;
    > > default:printf("b is %d\n",b);
    > > break;
    > > }
    > >
    > > this prints some garbage.
    > > ( yeah even though i got warning msg "unreachable code int b = 20" why
    > > is it declaring inside switch block but not initializing b)

    >
    > automatic variables (of which b is an example) are initialized as if by
    > an assignment (I'm talking casually here).
    >
    > So it's as if the block starts with :-
    > {
    > int b; /* declaration */
    > b = 20; /* initialization */
    > case 1: <etc>
    >
    > But in a switch statement only the operations following "case" or
    > "default" are executed. Hence the variable b is declared, but not
    > initialized.


    Your explanation seems reasonable. The control flow goes to "int b;"
    and "b" is defined. It also goes to "b = 20;", why doesn't the
    assignment take effect?

    What's the difference between a declaration and a statement? When does
    the declaration is executed and the variable "b" is defined? Why does
    the assignment statement above is skipped but the declaration is not?

    Thank you.
    , Sep 20, 2006
    #10
  11. posted:

    > wrote:
    >> sunny wrote:
    >>
    >> > Hi
    >> >
    >> > Why does C allows declaration of variable inside switch block.

    >>
    >> because it allows declaration of variables inside any braced block.

    >
    > Old C doesn't allow variables to be declared everywhere, right?



    No, all declarations must appear at the beginning of a block, before any
    expression statements.


    > What's the difference between a declaration and a statement?



    A declaration declares something. Here are some examples of declarations:

    int i;
    typedef unsigned UInt;
    int Func();

    (the first one is a definition as well as a declaration.)

    --

    Frederick Gotham
    Frederick Gotham, Sep 20, 2006
    #11
  12. <> wrote:

    > > > {
    > > > int b=20;
    > > > case 1: printf("b is %d\n",b);
    > > > break;
    > > > default:printf("b is %d\n",b);
    > > > break;
    > > > }


    > Your explanation seems reasonable. The control flow goes to "int b;"
    > and "b" is defined. It also goes to "b = 20;", why doesn't the
    > assignment take effect?


    The control flow does *not* go to b=20; read other replies in this
    thread, or look at the example in n869 6.8.4.2, paragraph 7.

    --
    C. Benson Manica | I *should* know what I'm talking about - if I
    cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Sep 20, 2006
    #12
  13. "sunny" <> writes:
    > Why does C allows declaration of variable inside switch block.
    > ex: foll prg does not gives "undeclared "b" error msg. but also does
    > not initialize b to 20
    > int a=1;
    > switch(a)
    > {
    > int b=20;
    > case 1: printf("b is %d\n",b);
    > break;
    > default:printf("b is %d\n",b);
    > break;
    > }
    >
    > this prints some garbage.
    > ( yeah even though i got warning msg "unreachable code int b = 20" why
    > is it declaring inside switch block but not initializing b)


    The C switch statement is actually a rather primitive construct. It's
    basically nothing more than a computed goto statement.

    The code above is equivalent to this:

    int a=1;
    if (a == 1) goto case_1; else goto case_default; /* switch(a) */
    {
    int b=20;
    case_1:
    printf("b is %d\n",b);
    goto end_of_switch; /* break; */
    case_default: printf("b is %d\n",b);
    goto end_of_switch; /* break; */
    }
    end_of_switch:;

    The grammar doesn't even require a block; it's just
    switch ( expression ) statement

    For example here's a rather perverse "hello, world" program:

    #include <stdio.h>
    int main(void)
    {
    switch (0) case 0: printf("Hello, world!\n");
    return 0;
    }

    You *can* write structured switch statements if you're careful. You
    can also write impenetrable spaghetti. Or you can write Duff's
    Device, which is a little of each.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Sep 20, 2006
    #13
  14. sunny

    Guest

    Christopher Benson-Manica wrote:
    > <> wrote:
    >
    > > > > {
    > > > > int b=20;
    > > > > case 1: printf("b is %d\n",b);
    > > > > break;
    > > > > default:printf("b is %d\n",b);
    > > > > break;
    > > > > }

    >
    > > Your explanation seems reasonable. The control flow goes to "int b;"
    > > and "b" is defined. It also goes to "b = 20;", why doesn't the
    > > assignment take effect?

    >
    > The control flow does *not* go to b=20; read other replies in this
    > thread, or look at the example in n869 6.8.4.2, paragraph 7.


    I understand that the control flow will go to one of the "case" and
    "default" entries in the following example. The code lines 4 and 5 are
    not in any of those entries.

    Code line 4 & 5 are in the same scope. I want to know why the variable
    "b" is defined at line 4 but the assignment at line 5 is skipped. When
    are declaration and statement executed respectively? Is declaration
    executed at compiling time but statement executed at run-time?

    Thank you.

    ....
    {
    int b; /*line 4*/
    b=20; /*line 5*/

    case 1:
    printf("b is %d\n",b);
    break;
    default:
    printf("b is %d\n",b);
    break;
    }
    , Sep 21, 2006
    #14
  15. sunny

    Jack Klein Guest

    On 20 Sep 2006 18:59:34 -0700, ""
    <> wrote in comp.lang.c:

    >
    > Christopher Benson-Manica wrote:
    > > <> wrote:
    > >
    > > > > > {
    > > > > > int b=20;
    > > > > > case 1: printf("b is %d\n",b);
    > > > > > break;
    > > > > > default:printf("b is %d\n",b);
    > > > > > break;
    > > > > > }

    > >
    > > > Your explanation seems reasonable. The control flow goes to "int b;"
    > > > and "b" is defined. It also goes to "b = 20;", why doesn't the
    > > > assignment take effect?

    > >
    > > The control flow does *not* go to b=20; read other replies in this
    > > thread, or look at the example in n869 6.8.4.2, paragraph 7.

    >
    > I understand that the control flow will go to one of the "case" and
    > "default" entries in the following example. The code lines 4 and 5 are
    > not in any of those entries.
    >
    > Code line 4 & 5 are in the same scope. I want to know why the variable
    > "b" is defined at line 4 but the assignment at line 5 is skipped. When
    > are declaration and statement executed respectively? Is declaration
    > executed at compiling time but statement executed at run-time?
    >
    > Thank you.
    >
    > ...
    > {
    > int b; /*line 4*/
    > b=20; /*line 5*/
    >
    > case 1:
    > printf("b is %d\n",b);
    > break;
    > default:
    > printf("b is %d\n",b);
    > break;
    > }


    An assignment statement is like any other statement. It is executed
    when the control flow of the program "passes through" that statement.

    Consider this snippet:

    int silly_func(int x)
    {
    int y = 0;

    if (x < -10)
    {
    y = -1;
    }
    else if (x > 10)
    {
    y = 1;
    }
    return y;
    }

    The first line inside the brace is a declaration with an initializer,
    so y is always initialized to 0 at the start of the function. As to
    the two assignment statements, either the first, the second, or
    neither of them will be executed. The control flow of the program
    does not "pass through" a statement that is controlled by a
    conditional expression that happens to be false.

    This is not just a property of the braces that I used after the "if"
    and "else if". You could remove them and result would be the same.
    Nor is it a special property of "if" and other conditional statements.

    Look at this similar (in result) example:

    int sillier_func(int x)
    {
    int y = 0;

    if (x < -10)
    goto negative;

    if (x > 10)
    goto positive;

    goto all_done;

    negative:
    y = -1;
    goto all_done;

    positive:
    y = 1;

    all_done:
    return y;
    }

    This function must perform exactly the same as the first. If y is
    between -11 and INT_MIN, it must return -1. If y is between 11 and
    INT_MAX, it must return 1. Otherwise, y is between -10 and +10
    inclusive, and the function returns 0.

    Here the assignments are at the same level, which also happens to be
    the same level as the declaration and initializer. But the goto
    statements cause just one, or neither, of the assignment statements to
    be initialized.

    When the flow of control goes "around", instead of "through" a
    statement, that statement is not executed.

    This also applies to declarations with initializers, although
    technically an initializer is not a statement. If the flow of control
    goes "around", rather than "through" a declaration with an
    initializer, which can only happen in a switch statement, the object
    has scope through the end of the block, but is not initialized either.

    Note that if you did this in a switch statement:

    switch (x)
    {
    int b = 0;
    case 1: printf("b = %d\n", b); break;
    }

    ....you produce undefined behavior when x is 1 because b is an
    uninitialized automatic variable.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Sep 21, 2006
    #15
  16. sunny

    Guest

    Jack Klein wrote:
    > On 20 Sep 2006 18:59:34 -0700, ""
    > <> wrote in comp.lang.c:
    > > I understand that the control flow will go to one of the "case" and
    > > "default" entries in the following example. The code lines 4 and 5 are
    > > not in any of those entries.
    > >
    > > Code line 4 & 5 are in the same scope. I want to know why the variable
    > > "b" is defined at line 4 but the assignment at line 5 is skipped. When
    > > are declaration and statement executed respectively? Is declaration
    > > executed at compiling time but statement executed at run-time?
    > >
    > > ...
    > > {
    > > int b; /*line 4*/
    > > b=20; /*line 5*/
    > >
    > > case 1:
    > > printf("b is %d\n",b);
    > > break;
    > > default:
    > > printf("b is %d\n",b);
    > > break;
    > > }

    >
    > An assignment statement is like any other statement. It is executed
    > when the control flow of the program "passes through" that statement.
    >
    > Consider this snippet:
    >
    > int silly_func(int x)
    > {
    > int y = 0;
    >
    > if (x < -10)
    > {
    > y = -1;
    > }
    > else if (x > 10)
    > {
    > y = 1;
    > }
    > return y;
    > }
    >
    > The first line inside the brace is a declaration with an initializer,
    > so y is always initialized to 0 at the start of the function. As to
    > the two assignment statements, either the first, the second, or
    > neither of them will be executed. The control flow of the program
    > does not "pass through" a statement that is controlled by a
    > conditional expression that happens to be false.


    Thank you. But I still have the anxious.

    In the following example, line 8 equals line 9 plus line 10. The
    variables "c" and "b" are defined but the initialization and assignment
    to them are skipped. I want to know when the declaration/definition is
    performed. When will their corresponding be performed? Why their
    initialization and assignment are skipped. Are these initialization and
    assignment performed later than the corresponding declaration? Is
    declaration executed at compiling time but statement executed at
    run-time?

    $ cat a.c
    #include <stdio.h>

    int main(void)
    {
    int a = 1;
    switch(a)
    {
    int c = 30; /*line 8*/
    int b; /*line 9*/
    b = 20; /*line 10*/

    case 1:
    printf("[case 1:] b: %d, c: %d\n", b + 1, c + 1);
    break;

    default:
    printf("[default:] b: %d, c: %d\n", b, c);
    break;
    }

    return 0;
    }
    $ cc -ansi -pedantic -Wall -W a.c
    a.c: In function `main':
    a.c:8: warning: unreachable code at beginning of switch statement
    $ ./a.out
    [case 1:] b: 1075108033, c: 1073833281
    $
    , Sep 21, 2006
    #16
  17. sunny

    Guest

    Frederick Gotham wrote:
    > posted:
    > > wrote:
    > >> sunny wrote:
    > >> > Why does C allows declaration of variable inside switch block.
    > >> because it allows declaration of variables inside any braced block.

    > > Old C doesn't allow variables to be declared everywhere, right?

    > No, all declarations must appear at the beginning of a block, before any
    > expression statements.


    Do you really mean that? In the following snippet, the variable i is
    defined after the function call expression statement, printf(),

    #include <stdio.h>

    int main(void){
    printf("hello world\n");
    int i;

    return 0;
    }

    and this is a complying code.
    , Oct 8, 2006
    #17
  18. >> >> > Why does C allows declaration of variable inside switch block.
    >> >> because it allows declaration of variables inside any braced block.
    >> > Old C doesn't allow variables to be declared everywhere, right?

    >> No, all declarations must appear at the beginning of a block, before any
    >> expression statements.

    >
    >Do you really mean that? In the following snippet, the variable i is
    >defined after the function call expression statement, printf(),
    >
    >#include <stdio.h>
    >
    >int main(void){
    > printf("hello world\n");
    > int i;
    >
    > return 0;
    >}
    >
    >and this is a complying code.


    Not in C89. It is in C99, but the context was "Old C"..
    Gordon Burditt, Oct 8, 2006
    #18
  19. sunny

    Guest

    Gordon Burditt wrote:
    > >> >> > Why does C allows declaration of variable inside switch block.
    > >> >> because it allows declaration of variables inside any braced block.
    > >> > Old C doesn't allow variables to be declared everywhere, right?
    > >> No, all declarations must appear at the beginning of a block, before any
    > >> expression statements.

    > >
    > >Do you really mean that? In the following snippet, the variable i is
    > >defined after the function call expression statement, printf(),
    > >
    > >#include <stdio.h>
    > >
    > >int main(void){
    > > printf("hello world\n");
    > > int i;
    > >
    > > return 0;
    > >}
    > >
    > >and this is a complying code.

    >
    > Not in C89. It is in C99, but the context was "Old C"..


    Thank you for the correction. I understand it now, the code in my last
    reply mixes declarations and statements that is forbidden in C89. A
    pair of additional braces make the declaration at the beginning of a
    block and legal in C89.

    #include <stdio.h>

    int main(void){
    printf("hello world\n");

    {
    int i;
    }

    return 0;
    }
    , Oct 8, 2006
    #19
    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. Casey Hawthorne
    Replies:
    12
    Views:
    43,152
    dainichi
    Jan 19, 2010
  2. kelvSYC
    Replies:
    6
    Views:
    7,213
    Richard Herring
    May 17, 2005
  3. Jeff
    Replies:
    2
    Views:
    930
    clintonG
    Sep 19, 2006
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,762
    Smokey Grindel
    Dec 2, 2006
  5. Ryan Taylor
    Replies:
    1
    Views:
    675
    Ryan Taylor
    Sep 9, 2004
Loading...

Share This Page