Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where you can and cannot declare new variables in C?

Tags:

c

declaration

I heard (probably from a teacher) that one should declare all variables on top of the program/function, and that declaring new ones among the statements could cause problems.

But then I was reading K&R and I came across this sentence: "Declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that begins a function". He follows with an example:

if (n > 0){     int i;     for (i=0;i<n;i++)     ... } 

I played a bit with the concept, and it works even with arrays. For example:

int main(){     int x = 0 ;      while (x<10){         if (x>5){             int y[x];             y[0] = 10;             printf("%d %d\n",y[0],y[4]);         }         x++;     } } 

So when exactly I am not allowed to declare variables? For example, what if my variable declaration is not right after the opening brace? Like here:

int main(){     int x = 10;      x++;     printf("%d\n",x);      int z = 6;     printf("%d\n",z); } 

Could this cause trouble depending on the program/machine?

like image 339
Daniel Scocco Avatar asked Dec 12 '11 12:12

Daniel Scocco


People also ask

Which variable is not allowed in C?

"Option C: $abc&123".The variable names must not begin with a number. Unlike some languages, C does not use any special characters in the prefix on variable names. In C, the variable name can only have letters, digits, and underscore and no special characters in middle.

Where should you declare variables in C?

The convention in C is has generally been to declare all such local variables at the top of a function; this is different from the convention in C++ or Java, which encourage variables to be declared when they are first used.

Can you declare variables in loops C?

There is no such thing as "construction" in C, so the space for the variable will simply be allocated into the stack (without any initialization), when the function is called. That's why there is a "zero" cost when declaring the variable inside a loop.


2 Answers

I also often hear that putting variables at the top of the function is the best way to do things, but I strongly disagree. I prefer to confine variables to the smallest scope possible so they have less chance to be misused and so I have less stuff filling up my mental space in each line on the program.

While all versions of C allow lexical block scope, where you can declare the variables depends of the version of the C standard that you are targeting:

C99 onwards or C++

Modern C compilers such as gcc and clang support the C99 and C11 standards, which allow you to declare a variable anywhere a statement could go. The variable's scope starts from the point of the declaration to the end of the block (next closing brace).

if( x < 10 ){    printf("%d", 17);  // z is not in scope in this line    int z = 42;    printf("%d", z);   // z is in scope in this line } 

You can also declare variables inside for loop initializers. The variable will only exist only inside the loop.

for(int i=0; i<10; i++){     printf("%d", i); } 

ANSI C (C90)

If you are targeting the older ANSI C standard, then you are limited to declaring variables immediately after an opening brace1.

This doesn't mean you have to declare all your variables at the top of your functions though. In C you can put a brace-delimited block anywhere a statement could go (not just after things like if or for) and you can use this to introduce new variable scopes. The following is the ANSI C version of the previous C99 examples:

if( x < 10 ){    printf("%d", 17);  // z is not in scope in this line     {        int z = 42;        printf("%d", z);   // z is in scope in this line    } }  {int i; for(i=0; i<10; i++){     printf("%d", i); }} 

1 Note that if you are using gcc you need to pass the --pedantic flag to make it actually enforce the C90 standard and complain that the variables are declared in the wrong place. If you just use -std=c90 it makes gcc accept a superset of C90 which also allows the more flexible C99 variable declarations.

like image 50
hugomg Avatar answered Oct 13 '22 00:10

hugomg


missingno covers what ANSI C allows, but he doesn't address why your teachers told you to declare your variables at the top of your functions. Declaring variables in odd places can make your code harder to read, and that can cause bugs.

Take the following code as an example.

#include <stdio.h>  int main() {     int i, j;     i = 20;     j = 30;      printf("(1) i: %d, j: %d\n", i, j);      {         int i;         i = 88;         j = 99;         printf("(2) i: %d, j: %d\n", i, j);     }      printf("(3) i: %d, j: %d\n", i, j);      return 0; } 

As you can see, I've declared i twice. Well, to be more precise, I've declared two variables, both with the name i. You might think this would cause an error, but it doesn't, because the two i variables are in different scopes. You can see this more clearly when you look at the output of this function.

(1) i: 20, j: 30 (2) i: 88, j: 99 (3) i: 20, j: 99 

First, we assign 20 and 30 to i and j respectively. Then, inside the curly braces, we assign 88 and 99. So, why then does the j keep its value, but i goes back to being 20 again? It's because of the two different i variables.

Between the inner set of curly braces the i variable with the value 20 is hidden and inaccessible, but since we have not declared a new j, we are still using the j from the outer scope. When we leave the inner set of curly braces, the i holding the value 88 goes away, and we again have access to the i with the value 20.

Sometimes this behavior is a good thing, other times, maybe not, but it should be clear that if you use this feature of C indiscriminately, you can really make your code confusing and hard to understand.

like image 25
haydenmuhl Avatar answered Oct 13 '22 01:10

haydenmuhl