Home > database >  Newbie question about C variable declarations
Newbie question about C variable declarations

Time:12-03

I'm reading an introducty book about C and I came across the following paragraph:

enter image description here

But the following code compiles with expected output:

#include <stdio.h>

int main()
{
    for(int i = 0; i<=10; i  )
    {
        int val = i   1;
        
        int x = val * val;
        
        printf("%d\n", x);
    }

    return 0;
}

I use https://www.onlinegdb.com/ and in the above code I declared many variables after the first executable statement. And this is to me does not match what the section from the book tells.

Am I misunderstanding what the book is telling?

CodePudding user response:

In strictly conforming C 1990, declarations could appear only at file scope (outside of function definitions) or at the start of a compound statement. The grammar for a compound statement in C 1990 6.6.2 was:

compound-statement
    { declaration-listopt statement-listopt }

That says a compound statement is { followed by zero or more declarations, then zero or more statements, then }. So the declarations had to come first.

In C 1999 6.8.2, this changed to:

compound-statement
    { block-item-listopt }

A block-item-list is a list of block-item, each of which may be a declaration or a statement, so declarations and statements could be freely mixed.

In your example, the declarations int val = i 1; and int x = val * val; do not appear after executable statements in their compound statement. The compound statement starts with the { immediately before int val = i 1;, so that declaration is at the start of the compound statement.

Another change was that the for grammar was changed from this in C 1990 6.6.5:

for ( expressionopt ; expressionopt ; expressionopt ) statement

to this choice of two forms in C 1999 6.8.5:

for ( expressionopt ; expressionopt ; expressionopt ) statement
for ( declaration expressionopt ; expressionopt ) statement

(Note the declaration includes a terminating ;.)

That explains why you can have int i = 0 in for(int i = 0; i<=10; i ).

CodePudding user response:

The book is referring to the original C specification from over 30 years ago known as "ANSI C" or "C89" or "C90". If we run a C compiler in C89 mode, -std=c89, we get a warning from your code...

cc -Wall -Wshadow -Wwrite-strings -Wextra -Wconversion -std=c89 -pedantic -g -fsanitize=address   -c -o test.o test.c
test.c:5:9: warning: variable declaration in for loop is a C99-specific feature [-Wc99-extensions]
    for(int i = 0; i<=10; i  )
        ^
test.c:5:9: warning: GCC does not allow variable declarations in for loop initializers before C99 [-Wgcc-compat]
2 warnings generated.

C99, the update to C made in 1999, made this untrue. Running your code with -std=c99 gives no warning. C99 made this and other impactful changes to the language, like // comments.

There is also C11 and the latest stable version of C is C17, but compiler support for both is spotty.


Why is this book referring to such an old version of the language? C has existed since 1978 and there are a lot of old code and old compilers out there. C Compilers have been very slow to fully adopt new standards making authors quite conservative. A big stumbling block was Microsoft Visual C did not implement C99 until 2013! So ANSI C was the lowest-common denominator for a very long time.

In recent years, C compilers have gotten better about standards compliance, so you can rely on C99 (which is old enough to drink) as your baseline.

CodePudding user response:

All variables in your example have been declared before used.

The declarations are:

int i ...;
int val ...;
int x ...;

Note that all declarations happen before the first function call in the corresponding block. On other words: i, val and x are all declared before the printf.

As stated in the comments: Some old books might refer to old versions of C. The variable declaration within the for loop came with C99 for example. Beginning with C99 you could also declare variables in the middle of the block. So you are allowed to declare some int y; after the printf and your code would still compile.

  •  Tags:  
  • c
  • Related