tags:

views:

300

answers:

4

Is the following code legal according to C99?

...
for(....) {
int x = 4;
...
}
...

You can assume that before line 3 the variable x was never declared.

C99 (PDF)

Until now I have only found the following, but I dont think that this is enough:

A block allows a set of declarations and statements to be grouped into one syntactic unit. The initializers of objects that have automatic storage duration, and the variable length array declarators of ordinary identifiers with block scope, are evaluated and the values are stored in the objects (including storing an indeterminate value in objects without an initializer) each time the declaration is reached in the order of execution, as if it were a statement, and within each declaration in the order that declarators appear.

From page 145 of that PDF.

+13  A: 

This is legal in both C99 and C89. Look at 6.8.2 , which defines compound statement

nos
Can you add a little more detail? Which one of the 3 cases am I at?Thanks!
quilby
@quilby: In C89 you can declare variables at the start of any new scope, which is a {} block. In C99 you can declare variables wherever you want in a scope.
Mads Elvheim
+1  A: 

Yes, you can create a variable at the beginning of any block. The variable is initialised each time the block is entered In C++, you can create them anywhere within the block.

anon
In C99 you can create them anywhere as well.
nos
Shows how much C99 coding I do :-)
anon
+3  A: 
for(....)
{
  int x=4;
  /*More code*/
}

Yeah this is legal in C99 but you are not allowed to access 'x' after the block.It would be Undefined Behaviour trying to access 'x' beyond its scope.

Prasoon Saurav
It would not be undefined behavior. It would be a compilation error to refer to `x` beyond its scope.
Rob Kennedy
+5  A: 

Yes, you can declare or define a variable anywhere you want in C99 (at the start of a block in C89).

You said:

"You can assume that before line 3 the variable x was never declared."

Even if it was previously declared, you could declare a new variable with the same name. Doing that prevents you from accessing the old variable within that block.

int x = 0;               /* old x */
printf("%d\n", x);       /* old x, prints 0 */
do {
    int x = 42;          /* new x */
    printf("%d\n", x);   /* new x, prints 42 */
} while (0);
printf("%d\n", x);       /* old x, prints 0 */


I've never tried the following in C99. I really don't know what happens :)
I'll try later, when I get access to a (almost) C99 compiler

int x = 0;
do {
    printf("%d\n", x);   /* old x? new x? crash? Undefined Behaviour? */
    int x = 42;
} while (0);

The C99 feature of declaring/defining variables wherever one wants is not a feature that makes me want to change :)

pmg
Old x. The scope of an automatic variable starts where it is defined, and runs to the end of the block.
Steve Jessop
To be honest, shadowing automatic variables is a pretty dubious anyway. Declaring them at the start of the block doesn't stop somebody trying to use the outer x, and getting the inner one instead because they forgot it was there. If you can trust someone to cope with shadowed variables at all, I think you have to trust them to know the scope rules - if you used a C99 compiler all the time, you'd know them pretty quickly too, because you'd know that if the outer x didn't exist at all, that C99 loop wouldn't compile.
Steve Jessop