Variable declaration placement in C
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?
It compiles successfully because GCC allows the declaration of s
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.
The declaration of c
at the start of a { }
block is part of the C89 standard; the block doesn't have to be a function.
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.
Grouping variable declarations at the top of the block is a legacy likely due to limitations of old, primitive C compilers. All modern languages recommend and sometimes even enforce the declaration of local variables at the latest point: where they're first initialized. Because this gets rid of the risk of using a random value by mistake. Separating declaration and initialization also prevents you from using "const" (or "final") when you could.
C++ unfortunately keeps accepting the old, top declaration way for backward compatibility with C (one C compatibility drag out of many others...) But C++ tries to move away from it:
- The design of C++ references does not even allow such top of the block grouping.
- If you separate declaration and initialization of a C++ local object then you pay the cost of an extra constructor for nothing. If the no-arg constructor does not exist then again you are not even allowed to separate both!
C99 starts to move C in this same direction.
If you are worried of not finding where local variables are declared then it means you have a much bigger problem: the enclosing block is too long and should be split.
https://wiki.sei.cmu.edu/confluence/display/c/DCL19-C.+Minimize+the+scope+of+variables+and+functions