63

Can someone elaborate on the following gcc error?

$ gcc -o Ctutorial/temptable.out temptable.c 
temptable.c: In function ‘main’:
temptable.c:5: error: ‘for’ loop initial declaration used outside C99 mode

temptable.c:

...
/* print Fahrenheit-Celsius Table */
main()
{
    for(int i = 0; i <= 300; i += 20)
    {
        printf("F=%d C=%d\n",i, (i-32) / 9);        
    }
}

P.S: I vaguely recall that int i should be declared before a for loop. I should state that I am looking for an answer that gives a historical context of C standard.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Midnight Blue
  • 5,061
  • 10
  • 41
  • 46
  • 2
    Check out this previous question related to C variable declaration for more info: http://stackoverflow.com/questions/288441/variable-declaration-placement-in-c – Kyle Walsh Aug 17 '09 at 13:12
  • Note that the temperature conversion formula is incorrect; in integer arithmetic, it should be `(5 * (i - 32)) / 9` (the `5` is missing). Usually, you need floating point arithmetic – but then you need to change your printf format from `C=%d` to `C=%./2f` or something similar too (and you convert with `(5.0 * (i - 32)) / 9.0`). – Jonathan Leffler Sep 02 '19 at 17:50

2 Answers2

106
for (int i = 0; ...) 

is a syntax that was introduced in C99. In order to use it you must enable C99 mode by passing -std=c99 (or some later standard) to GCC. The C89 version is:

int i;
for (i = 0; ...)

EDIT

Historically, the C language always forced programmers to declare all the variables at the begin of a block. So something like:

{
   printf("%d", 42); 
   int c = 43;  /* <--- compile time error */

must be rewritten as:

{
   int c = 43;
   printf("%d", 42);

a block is defined as:

block := '{' declarations statements '}'

C99, C++, C#, and Java allow declaration of variables anywhere in a block.

The real reason (guessing) is about allocating internal structures (like calculating stack size) ASAP while parsing the C source, without go for another compiler pass.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
dfa
  • 114,442
  • 31
  • 189
  • 228
  • 7
    Just a note: when using the c99 version, don't forget that the declared variable is local to the for-loop block, and will not exist afterward, when it has gone out of scope. – ely Mar 30 '16 at 02:42
  • 4
    An additional note that may be of historical interest. One way around this rule prior to the C99 standard was creating a block within a block. You would declare a variable in the middle of a block, and surround it and code that used it with more bracers {} – Neil Roy Dec 29 '16 at 05:40
  • 1
    It is also worth mention that , for instance, on new versions of GCC, the default version of C is updated to a more updated version then C89 --> so this whole issue WONT create a compilation error in the first place...(I'm using gcc 5.4.0 on Ubuntu 16.04 and did not have any compilation errors not warnings for this snippet of code). – Guy Avraham Oct 11 '17 at 08:35
  • Just add a word if someone really wants to experiment with it with compiler flag `-std=c89`: don't forget to add `-pedantic` to ask the compiler to get serious. – aafulei Sep 12 '19 at 07:37
20

Before C99, you had to define the local variables at the start of a block. C99 imported the C++ feature that you can intermix local variable definitions with the instructions and you can define variables in the for and while control expressions.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143