Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do the older C language specs require function-local variables to be declared up-front?

In the C programming language, all of the language revisions I have worked with enforced up-front variable declarations before any non-declarative/assignative expressions would be evaluated. C++ seems to have waived this requirement from all versions. I also recognize more modern version of C have waived this requirement as well, but I have yet to use any of those standards.

The question I have is this: What historic reason was there for preventing the C language from declaring freely on-demand instead of up front?

Obviously there are a number of reasons that come to mind from an engineering standpoint, but none of them seem especially plausible to me.

  1. Preventing an obscure compiler behavioral error from occurring (such as infinite parsing loops, a massive memory bloat for evaluation, or some weird corner cases with Macros.)
  2. Preventing undesirable compiler output. This could be anything from symbol output muddling the debug process and the ease of development of debugging tools, to unexpected stack storage orders.
  3. Readability. I find this hard to swallow as well, seeing as C, while designed for readability compared to other languages of the era, did not enforce this type of structure nearly anywhere else. (Unless you see prototyping as being a similar enforcement, but if I recall prototypes were added in the '89 spec.)
  4. Implementation complexity and practical reasons. This is the one I'm most inclined to believe. As engineers we have to make certain considerations in order to ship a viable product in a time-frame allotted. While I will grant that the professional landscape for Computer Science and Software Engineering have both changed dramatically, Business is still business. At the end of the day I'm sure Bell wanted a finished product that could be used in the Unix programming environment to showcase what they had achieved.

Does anyone have any good sources backing up any of the above? Did I miss something entirely? We can speculate from dawn till dusk, but I'm looking for good hard references.

like image 636
Daniel Green Avatar asked Jan 14 '13 18:01

Daniel Green


People also ask

Why do we need to declare variables in C program?

Why do We Need to Declare a Variable in C? Basically, we need to declare a variable to store various types of data in the program. So to perform some operations or tasks with the data, we need to store them in the computer's memory location.

Why should we declare a variable before using it?

It's best to declare variables when you first use them to ensure that they are always initialized to some valid value and that their intended use is always apparent. The alternative is typically to declare all variables in one location, typically at the top of the block or, even worse, at the top of a function.

Can you use a variable before it is declared in C?

Before you can use a variable in C, you must declare it. Variable declarations show up in three places: Outside a function. These declarations declare global variables that are visible throughout the program (i.e. they have global scope).

Can we declare variable anywhere in C program?

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). You can also declare variables inside for loop initializers.


1 Answers

Looking at the early (6th edition Unix, 1975) C manual from Dennis Ritchie's home page, in that version function-local variables could only be declared at the beginning of a function:

The function-statement is just a compound statement which may have declarations at the start.

function-statement: { declaration-listopt statement-list }

declaration-list is not defined (an omission), but can be readily assumed to have grammar:

declaration-list: declaration declaration-listopt.

No other compound statement is allowed to contain variable (or indeed any) declarations.

This obviously simplifies the implementation; in the early compiler source code c02.c the function header function blkhed() only needs to sum the stack space used by auto variable declarations, at the same time recording their stack offset, and emit code to bump the stack pointer by the appropriate amount. On function exit (by return or falling off the end) the implementation just needs to restore the saved stack pointer.

The fact that K&R feels necessary to state that "declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that begins a function" is a hint that at that point it was a relatively recent feature. It also indicates that combined declaration-initialization syntax was also a recent feature, and indeed in the 1975 manual declarators cannot have initializers.

The 1975 manual in section 11.1 specifically states that:

C is not a block-structured language; this may fairly be considered a defect.

Block-statement and initialized declarations (K&R) address that defect, and mixed declarations and code (C99) are the logical continuation.

like image 107
ecatmur Avatar answered Oct 11 '22 13:10

ecatmur