Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rationale for pre-C99 C not having initial declarations in for loops?

Tags:

c

c89

ansi-c

Why did the original C language not support initial declarations in for loop initializations?

Obviously the original creators, and then the pre-C99 standardizations, didn't specify it that way. But I can't seem to find any rationale for why that design choice was made.

The closest thing to an answer I seem to find is this answer explaining how mixing declarations and code was prohibited in order to allow for compilers to be single-pass back when that was important. At first glance it makes sense that declarations in a for loop statement would have the same/similar problems as declarations mixed with code.

But, pre-C99 C did support declarations at the start of blocks:

{
    unsigned int i;
    for(i = 0; i < WHATEVER; i += 1)
    {
        /* ... */
    }
}

I don't personally see how the compiler logic for that is substantially different than for this:

for(unsigned int i = 0; i < WHATEVER; i += 1)
{
    /* ... */
}

Seems to me that if a compiler can do the former single-pass, it could also do the latter. It might require that a for statement always create a scope block (even if followed by just one statement and not a { ... } block of statements), but I can't think of a way for such semantics to break any other pre-C99 C code (either the for statement is followed by a block in which case it's already "scoped", or it's followed by a single statement, in which case a new declaration wouldn't have been allowed in that single statement anyway).

So, why was this syntax "feature" initially omitted? Am I wrong in thinking that it would've been trivial to support without violating performance goals of the time? Did known language parser/compiler techniques at the time make it seem harder? Did it just get omitted because of minimalist design/mentality, since functionally it was possible to do the same thing (block around for loop)? Or was there an explicit language design reason against it (e.g. how Go initially excluded exceptions because the designers thought that made for a better language)?

Where I've looked

  • I've tried finding an answer to this here and through general web-search-fu, with no luck: all search terms I thought of seem to be saturated with confused questions about C for loop initial declarations, the "used outside of C99 mode" error message, etc. (Except the search term "rationale", which guided me to useful information, but nothing that answered this specifically).
  • I searched over this article by Dennis Ritchie himself on developing the language, and didn't spot anything.
  • I searched through my copy of The C Programming Language (2nd Edition), first reading the actual for loop explaining section, then checking the index for other mentions of the "for"/"for loop". I've read over a couple of other places I thought might mention it, but found nothing.
like image 876
mtraceur Avatar asked Jan 31 '16 06:01

mtraceur


People also ask

How do I fix error for loop initial declarations are only allowed in C99 mode?

This happens because declaring variables inside a for loop wasn't valid C until C99(which is the standard of C published in 1999), you can either declare your counter outside the for as pointed out by others or use the -std=c99 flag to tell the compiler explicitly that you're using this standard and it should interpret ...

How do you solve the error for loops initial declarations are only allowed in C99 or C11 mode?

solution. Declaring variables in a for loop is only allowed in C99 or C11 mode, and you need to select C99 as the language standard under Tools/complier option/code generation .

What is C99 mode in C?

There is a compiler switch which enables C99 mode, which amongst other things allows declaration of a variable inside the for loop. To turn it on use the compiler switch -std=c99. Or as @OysterD says, declare the variable outside the loop.


1 Answers

I don't believe there was any specific decision to exclude such features, nor rationale mounted to do so.

As romantic as it may seem to believe the designers (Kernighan, Ritchie, etc) thought of all the possibilities, and excluded features only after deep and meaningful consideration, the reality is that the early years of designing C (like quite a few other programming languages) followed a much more humble philosophy something like "Start small, don't sweat about adding features unless programmers are being PREVENTED from doing something".

Features like variable initialisation in for loops are programmer convenience - their absence didn't stop things being done. So, even if there was someone begging or campaigning for such a feature (which there probably wasn't), it probably went down in the priority order.

As to how things evolved .....

Before 1999, variable declarations were at the start of blocks in C (code commenced with { and ending at the closing }), not within other statements. This is the way things originally worked in pre-standard (K&R) C, and preceding languages like B (which was actually a cut-down derivative of preceding languages).

Variable declaration/initialisation within a for loop was introduced first into C++. It appeared pretty early on (e.g. Section 19 in the ARM), and was eventually introduced in the first C++ standard that was ratified in late 1998.

There was some discussion in the C standard committee, during the process of drafting the C++ standard (which took a decade) about adopting some features of C++ into C. That discussion was often mostly along the lines of "would anything else in C break if we added this?". A number of compiler vendors had already implemented several such features into their C compilers as optional extensions (or their C compilers were actually C++ compilers, with settings to disable C++ features incompatible with C), so discussion about adding those features was pretty brief. Therefore, those features easily added to C from C++ appeared in the 1999 C standard. Variable declaration/initialisation within a for loop was one of those features.

From that history, there is no evidence of any particular decision or rationale to exclude such features from early C - in short, it probably simply wasn't thought of.

like image 151
Peter Avatar answered Sep 20 '22 05:09

Peter