The C language and its typical implementations are designed to be used easily by experts. The language is terse and expressive. There are few restrictions to keep the user from blundering. A user who has blundered is often rewarded by an effect that is not obviously related to the cause.
In this paper, we will look at some of these unexpected rewards. Because they are unexpected, it
may well be impossible to classify them completely. Nevertheless, we have made a rough effort to do so by looking at what has to happen in order to run a C program. We assume the reader has at least a passing acquaintance with the C language.
Section 1 looks at problems that occur while the program is being broken into tokens.
Section 2 follows the program as the compiler groups its tokens into declarations, expressions, and statements.
Section 3 recognizes that a C program is often made out of several parts that are compiled separately and bound together.
Section 4 deals with misconceptions of meaning: things that happen while the program is actually running.
Section 5 examines the relationship between our programs and the library routines they use.
In section 6 we note that the program we write is not really the program we run; the preprocessor has gotten at it first.
Finally, section 7 discusses portability problems: reasons a program might run on one implementation and not another.
