sign in | join about | help | sitemap
Connecting Tech Pros Worldwide
Neil Zanella's Avatar

C99: variable declarations inside switch statements


Question posted by: Neil Zanella (Guest) on November 13th, 2005 09:39 PM

Hello,

Unlike in pre-C99 versions of C where variables can only be defined at the
beginning of blocks, C99 allows variables to be defined in arbitrary
places inside blocks. However, gcc 3.2.2 seems to reveal that there
are still places where this is illegal. For instance, consider the
following code snippet.

int main(void) {
int i = 0;
switch (i) {
case 0:
char ch;
break;
}
}

Here the compiler complains with the error:

hello.c: In function `main':
hello.c:6: parse error before "char"

It seems like declaring a variable inside a switch statement is illegal.
Anyone know why this is the case. After all, the following compiles fine
with gcc 3.2.2:

int main(void) {
int i = 0;
switch (i) {
case 0: {
char ch;
break;
}
}
}

The only difference is the introduction of the block within the C
statement. Anyone know of similar cases where it is illegal to declare
variable in places where we would expect it to be legal in C99? Also,
can anyone explain the reason for the compiler complaint?

Thanks,

Neil

5 Answers Posted
Sheldon Simms's Avatar
Guest - n/a Posts
#2: Re: C99: variable declarations inside switch statements

On Mon, 27 Oct 2003 00:13:06 -0330, Neil Zanella wrote:
[color=blue]
> Unlike in pre-C99 versions of C where variables can only be defined at the
> beginning of blocks, C99 allows variables to be defined in arbitrary
> places inside blocks. However, gcc 3.2.2 seems to reveal that there
> are still places where this is illegal. For instance, consider the
> following code snippet.[/color]

You can't count on conformance of current versions of GCC
to the C99 standard. With that out of the way I'll continue.
[color=blue]
> int main(void) {
> int i = 0;
> switch (i) {
> case 0:
> char ch;
> break;
> }
> }
>
> Here the compiler complains with the error:
>
> hello.c: In function `main':
> hello.c:6: parse error before "char"
>
> can anyone explain the reason for the compiler complaint?[/color]

The answer is in the C99 grammar. Declarations can appear at
any place within a block because of these productions:

A.2.3 Statements

(6.8.2) compound-statement: { block-item-list? }
(6.8.2) block-item-list: block-item
block-item-list block-item
(6.8.2) block-item: declaration
statement

But you can't put a declaration after a case construct because
of these productions:

A.2.3 Statements

(6.8) statement: labeled-statement
(6.8.1) labeled-statement: case constant-expression : statement

IOW, only a statement can follow a case.

-Sheldon


Christian Bau's Avatar
Guest - n/a Posts
#3: Re: C99: variable declarations inside switch statements

In article
<Pine.LNX.4.44.0310270007370.6912-100000@garfield.cs.mun.ca>,
Neil Zanella <nzanella@cs.mun.ca> wrote:
[color=blue]
> Hello,
>
> Unlike in pre-C99 versions of C where variables can only be defined at the
> beginning of blocks, C99 allows variables to be defined in arbitrary
> places inside blocks. However, gcc 3.2.2 seems to reveal that there
> are still places where this is illegal. For instance, consider the
> following code snippet.
>
> int main(void) {
> int i = 0;
> switch (i) {
> case 0:
> char ch;
> break;
> }
> }
>
> Here the compiler complains with the error:
>
> hello.c: In function `main':
> hello.c:6: parse error before "char"
>
> It seems like declaring a variable inside a switch statement is illegal.
> Anyone know why this is the case. After all, the following compiles fine
> with gcc 3.2.2:[/color]

No, declaring a variable inside a switch statement is not illegal.
However, the syntax is slightly different then you think it is: When you
write

switch (i) {
<body of switch statement>
}

the body of the switch statement can contain the following in any order:

Unlabeled statements
Labeled statements
Declarations

case 0: char ch;

would be a labeled declaration, and they are not allowed. Write

case 0: ;
char ch;
break;

instead.
Neil Zanella's Avatar
Guest - n/a Posts
#4: Re: C99: variable declarations inside switch statements

Hello,

Quite interesting. I wonder whether adding a rule to the C99 grammar for
accepting declarations following labeled statements would cause the
resulting grammar to be ambiguous (I doubt it), or whether there
would be some shift/reduce, reduce/shift, reduce/reduce conflicts
of some sort (more likely). How would such conflicts arise in
such a situation?

Thanks,

Neil

Sheldon Simms <sheldonsimms@yahoo.com> wrote:
[color=blue]
> The answer is in the C99 grammar. Declarations can appear at
> any place within a block because of these productions:
>
> A.2.3 Statements
>
> (6.8.2) compound-statement: { block-item-list? }
> (6.8.2) block-item-list: block-item
> block-item-list block-item
> (6.8.2) block-item: declaration
> statement
>
> But you can't put a declaration after a case construct because
> of these productions:
>
> A.2.3 Statements
>
> (6.8) statement: labeled-statement
> (6.8.1) labeled-statement: case constant-expression : statement
>
> IOW, only a statement can follow a case.
>
> -Sheldon
>
> On Mon, 27 Oct 2003 00:13:06 -0330, Neil Zanella wrote:
>[color=green]
> > int main(void) {
> > int i = 0;
> > switch (i) {
> > case 0:
> > char ch;
> > break;
> > }
> > }[/color][/color]
Sheldon Simms's Avatar
Guest - n/a Posts
#5: Re: C99: variable declarations inside switch statements


top-posting corrected

On Tue, 28 Oct 2003 03:00:59 -0800, Neil Zanella wrote:[color=blue]
>
> Sheldon Simms <sheldonsimms@yahoo.com> wrote:
>[color=green]
>> On Mon, 27 Oct 2003 00:13:06 -0330, Neil Zanella wrote:
>>[color=darkred]
>> > int main(void) {
>> > int i = 0;
>> > switch (i) {
>> > case 0:
>> > char ch;
>> > break;
>> > }
>> > }[/color]
>>
>> The answer is in the C99 grammar. Declarations can appear at
>> any place within a block because of these productions:
>>
>> A.2.3 Statements
>>
>> (6.8.2) compound-statement: { block-item-list? }
>> (6.8.2) block-item-list: block-item
>> block-item-list block-item
>> (6.8.2) block-item: declaration
>> statement
>>
>> But you can't put a declaration after a case construct because
>> of these productions:
>>
>> A.2.3 Statements
>>
>> (6.8) statement: labeled-statement
>> (6.8.1) labeled-statement: case constant-expression : statement
>>
>> IOW, only a statement can follow a case.
>>
>> -Sheldon
>>[/color]
> Quite interesting. I wonder whether adding a rule to the C99 grammar for
> accepting declarations following labeled statements would cause the
> resulting grammar to be ambiguous (I doubt it), or whether there
> would be some shift/reduce, reduce/shift, reduce/reduce conflicts
> of some sort (more likely). How would such conflicts arise in
> such a situation?[/color]

I don't know if the C standards committee worries too much about
those kinds of problems when writing the grammar. I wouldn't in any
case. The grammer in the standard isn't supposed to be directly
usable in bison.

FWIW C++ *does* allow declarations after case and other labels with
these productions:

ISO/IEC 14882:1998(E)
A.5
statement: labeled-statement
declaration-statement

labeled-statement: case constant-expression : statement

declaration-statement : block-declaration

where block-declaration is the kind of declaration that can occur
inside a block (i.e. - no function definitions, template declaration,
etc.)

-Sheldon



Christian Bau's Avatar
Guest - n/a Posts
#6: Re: C99: variable declarations inside switch statements

In article <b68d2f19.0310280300.2b25f478@posting.google.com>,
Join Bytes! (Neil Zanella) wrote:
[color=blue]
> Hello,
>
> Quite interesting. I wonder whether adding a rule to the C99 grammar for
> accepting declarations following labeled statements would cause the
> resulting grammar to be ambiguous (I doubt it), or whether there
> would be some shift/reduce, reduce/shift, reduce/reduce conflicts
> of some sort (more likely). How would such conflicts arise in
> such a situation?[/color]

Unlikely that this could introduce any conflicts.

We assume that there is no conflict between unlabeled statement and
declaration (otherwise C has a big problem anyway). Labels are quite
trivial to recognise and to distinguish from anything else. Once the
label is recognised, you are left again with the task of distinguishing
between unlabeled statement and declaration.
 
Not the answer you were looking for? Post your question . . .
196,835 members ready to help you find a solution.
Join Bytes.com

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 196,835 network members.
Post your question now . . .
It's fast and it's free

Popular Articles

Top Community Contributors