views:

3882

answers:

4

I long thought that in C, all variables had to be declared at the beginning of the function. I know that in C99, the rules are the same as in C++, but what are the variable declaration placement rules for C89/ANSI C?

The following code compiles successfully with "gcc -std=c89" and "gcc -ansi":

#include <stdio.h>
int main() {
    int i;
    for (i = 0; i < 10; i++) {
        char c = (i % 95) + 32;
        printf("%i: %c\n", i, c);
        char *s;
        s = "some string";
        puts(s);
    }
    return 0;
}

Shouldn't the declarations of c and s cause an error in C89/ANSI mode?

+23  A: 

It compiles successfully because GCC allows it as a GNU extension, even though it's not part of the C89 or ANSI standard. If you want to adhere strictly to those standards, you must pass the -pedantic flag.

mipadi
Wow. Thanks! I didn't know that.
mcjabberz
It is probably worth noting that only the declaration of `s` is an extension (from C89 point of view). The declaration of `c` is perfectly legal in C89, no extensions needed.
AndreyT
+15  A: 

For C89, you must declare all of your variables at the beginning of a scope block.

So, your char c declaration is valid as it is at the top of the for loop scope block. But, the char* s declaration should be an error.

Kiley Hykawy
Quite correct. You can declare variables at the beginning of any { ... }.
Artelius
+4  A: 

From a maintainability, rather than syntactic, standpoint, there are at least three trains of thought:

  1. Declare all variables at the beginning of the function so they'll be in one place and you'll be able to see the comprehensive list at a glance.

  2. Declare all variables as close as possible to the place they're first used, so you'll know why each is needed.

  3. Declare all variables at the beginning of the innermost scope block, so they'll go out of scope as soon as possible and allow the compiler to optimize memory and tell you if you accidentally use them where you hadn't intended.

I generally prefer the first option, as I find the others often force me to hunt through code for the declarations. Defining all variables up front also makes it easier to initialize and watch them from a debugger.

I'll sometimes declare variables within a smaller scope block, but only for a Good Reason, of which I have very few. One example might be after a fork(), to declare variables needed only by the child process. To me, this visual indicator is a helpful reminder of their purpose.

Adam Liss
I use option 2 or 3 so it is easier to find the variables -- because the functions shouldn't be so big that you can't see the variable declarations.
Jonathan Leffler