I’m working through K&R and I notice that their code is extremely tightly spaced.
I haven’t developed C since at University, but professionally most source from other languages I’ve worked in has used blank lines to aid readability.
Is C generally more tightly packed or is it a historical matter related to display size in the 70s?
Exercise 1-16 seems to hinder readability by, for example, an if
immediately after for
loop that doesn’t have braces.
/* mygetline: read a line into s, return length */
int mygetline(char s[], int lim)
{
int c,i;
for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='n'; ++i)
s[i] = c;
if (c == 'n') {
s[i] = c;
++i;
}
s[i] = '';
return i;
}
7
Every line of code you keep on the screen is saved time when programming.
In the days of the K&R being written, the screens were 80 characters wide by 24 lines tall. This is all that you could see at the time on one page. Visual editors were not yet written – you had tools that were more along the lines of ed (written in 1971, C is from 1972).
When working in such an environment, vertical space is important. Unnecessary braces to denote a block represent a ‘wasted’ line on the screen. Putting an open curly brace on its own line is another wasted line. Elses with ears } else {
represents two lines saved on the screen.
When tracing program flow it can become difficult to keep things in your head, your code size becomes limited to about one screen size (even today that is true), maybe two. While printing lines in line editors isn’t cumbersome it isn’t just scrolling down the mouse on the side of the screen (or hitting page down in vi), it is commands such as .,.+10p
to print the next ten lines, or .-10,.+10
to “scroll up 10 lines and display the next ten lines too” – it isn’t exactly easy either to navigate the code, or move from “page” to “page”.
If one looks at How many lines of code is too many? on StackOverflow, one will see several references to “screen size”.
We unconsciously can keep in our head what we can see – swapping out to screen. If you were to be asked a question about something that is on the page of a book you are reading, it is in short term memory and you can quickly see it and look at it to get the rest of the memory quickly. When asked about something two pages ago, you may have to go back and refresh your memory. This is even more critical when working with programs because the small things matter (x++ vs ++x
). So now you’ve got to go back and “scroll” with ed, which takes some thought too (which becomes one of the spots of seven plus or minus two and pushed out something else).
On the other “not space saving” things in the block of code and their reasons…
If anything, I am surprised at the code at not saving more space:
int mygetline(char s[], int lim)
{
int c,i;
for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='n'; ++i)
s[i] = c;
if (c == 'n')
s[i++] = c;
s[i] = '';
return i;
}
By moving the increment into the assignment of the array two lines can be removed (and yes, there are even more lines that can be removed for more dense code, the K&R appears to maintain the code style of the open brace for a function on a line by itself and a blank line between declarations and code).
The open brace on a line by itself is likely from the original style of C functions declaration. From Section 1.7 in K&R (second edition):
/* power: raise base to n-th power; n >= 0 */
/* (old-style version) */
power(base, n)
int base, n;
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i)
p = p * base;
return p;
}
You can see the awkwardness of moving the open curly for power
onto a previous line – and if anything, it helps keep the function declaration identifiable.
Likewise, keeping a declaration block at the top and then a blank line. This was important in some early compliers where declarations could only happen at the top of a block. Separating the two helped ensure you didn’t make a mistake by interweaving declarations and code (this was prohibited as recently as C89 – C89, Mixing Variable Declarations and Code). Making the declaration block separate could save you a pass through the complier (not necessarily a quick thing).
4
K&R was written in the heart of the “Glass TTY” era, when the standard resolution screen was 80 characters by 24 lines. Whitespace was a luxury that usually lost out to the desire to keep the relevant lines of code visible.
There is a historical dimension to your question. Computers were not always having a screen attached to them. Just think of old command line/ DOS boxes having limited number of lines per screen. Then you can imagine that a programmer wanted to see as much code as possible at once.
Furthermore with teletypewriters, etc. you could not even be sure to have a screen. Blank lines were a waste.
2