Variable declaration placement in C

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.


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.


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


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.

Tags:

C

Declaration

C89