1

Possible Duplicate:
Why was mixing declarations and code forbidden up until C99?

There are a handful of questions related to this warning: ISO C90 forbids mixed declarations and code but they do not address the question of WHY this is in the C90 standard in the first place.

So - why this stipulation?

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
jsj
  • 9,019
  • 17
  • 58
  • 103
  • because Ritchie and team disliked mixed declarations. – Aniket Inge Jan 31 '13 at 18:17
  • 1
    @Aniket It's not that they disliked it - it's that it's easier to parse/compile code that has all the declarations at the beginning of the code. The parser can then linearly walk the AST and allocate stack space for the variables. If this isn't a requirement, then it has to AST-walk twice, collecting all the variables and types before continuing the translation. –  Jan 31 '13 at 18:22
  • Nested blocks may contain their own declarations, so the compiler still has to walk the AST. – nneonneo Jan 31 '13 at 18:25
  • http://www.jcmit.com/memoryprice.htm – Hans Passant Jan 31 '13 at 18:27
  • @Aniket - Hey you found a duplicate.. well done – jsj Jan 31 '13 at 18:35
  • google/research before asking a question. @trideceth12 – Aniket Inge Jan 31 '13 at 18:36
  • A workaround for this is to introduce scope, your declarations have to be at the beginning of the scope, not the beginning of the function. So if you are like most modern coders, especially the C++ coders, you like declare your variables when you use them. So, just add some { } within your function and viola you've got a new scope where you can declare your variable and then use it immediately. – Josh Petitt Jan 31 '13 at 20:00
  • @nneonneo, a simple strategy to handle nested blocks is to just create a stack frame for it, as if it was a function called at that point only. In fact, if you have several such blocks side by side, you want to get rid of the variables of one before entering the other (reusing the space). – vonbrand Feb 01 '13 at 00:29

1 Answers1

4

The biggest reason I know of is that it simplifies the language grammar and parser.

With the declarations up front, a block of code must look like

{
    <declarations>
    <stmts>
}

and consequently the definition of <stmts> is simplified because it doesn't have to involve declarations. This, in turn, simplifies the parser, since it need only disambiguate statements from declarations at the start of a block.

In fact, this particular definition of the code block is codified in the standard:

3.6.2 Compound statement, or block

Syntax

          compound-statement:
                  {  declaration-list<opt> statement-list<opt> }

          declaration-list:
                  declaration
                  declaration-list declaration

          statement-list:
                  statement
                  statement-list statement
nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • So it's more of a "this will make writing the compiler easy" thing rather than "this will make the code 'better'"? – jsj Jan 31 '13 at 18:20
  • I would disagree on the grammar part. `: |` `: ` `otherstmt: ` not too difficult to parse if we have another type. Most compilers were being made with Lex/Yacc anyway. There has to be some other reason – Aniket Inge Jan 31 '13 at 18:20
  • @trideceth12 Yes, it is, see my comment on the question itself. –  Jan 31 '13 at 18:23
  • @Aniket: Check out A.1.2.2 and A.1.2.3 from [the spec](http://flash-gordon.me.uk/ansi.c.txt), and tell me it would be easy to combine the two monstrous definitions for 'declaration' and 'statement'. Also, since statements are illegal in global scope, declarations and statements have to be treated separately anyway. – nneonneo Jan 31 '13 at 18:26
  • 1
    @nneonneo Well, they did combine it in C99. But it's of significance that the original ANSI C was born out of C as developed in the 1970's. Things were different then. – nos Jan 31 '13 at 18:28
  • Its definitely simplicity of the compiler because of memory constraints on the PCs back then. – Aniket Inge Jan 31 '13 at 18:31
  • Another issue to consider is that absent a rule forbidding any declarations after a label, it's possible to use a "goto" to jump from a spot after a declaration to a spot preceding it, and from there to a spot after--a possibility that creates semantic murkiness about object lifetime since execution will have left the variable's scope, but not the containing block – supercat Jun 21 '16 at 18:04