function apple (){ / visible everywhere / }
extern function pear () { / visible everywhere / }
static function turnip(){ / not visible outside this file / }
In practice, almost everyone tends to define functions without adding extra storage-class specifiers, so
global scope prevails.
With the benefit of practical experience, default global visibility has been conclusively and repeatedly
demonstrated to be a mistake. Software objects should have the most limited scope by default.
Programmers should explicitly take action when they intend to give something global scope.
The problem of too much scope interacts with another common C convention, that of interpositioning.
Interpositioning is the practice of supplanting a library function by a user-written function of the same
name. Many C programmers are completely unaware of this feature, so it is described in the chapter
on linking. For now, just make the mental note: "interpositioning—I should learn more about that."
The problem of too wide scope is often seen in libraries: one library needs to make an object visible to
another library. The only possibility is to make it globally known; but then it is visible to anyone that
links with the library. This is an "all-or-nothing" visibil-ity—symbols are either globally known or not
known at all. There's no way to be more selective in revealing information in C.
The problem is made worse by the fact that you can't nest function definitions inside other functions,
as you can in Pascal. So a collection of "internal" functions for one big function have to be outside it.
Nobody remembers to make them static, so they're globally visible by default. The Ada and Modula-2
languages both address this problem in a man-ageable way by having program units specify exactly
what symbols they are exporting and what they are importing.
Sins of Mission
The "sins of mission" category covers things in C that just seem misdirected, or a bad fit to the
language. This includes features like the brevity of C (caused in part by excessive reuse of symbols)
and problems with operator precedence.
Overloading the Camel's Back
One problem is that C is so terse. Just adding, changing, or omitting a single character often gives you
a program that is still valid but does something entirely different. Worse than that, many symbols are
"overloaded"—given different meanings when used in different contexts. Even some keywords are
overloaded with several meanings, which is the main reason that C scope rules are not intuitively clear
to programmers. Table 2-1 shows how similar C symbols have multiple different meanings.
Table 2-1. Symbol Overloading in C
Symbol Meaning
static Inside a function, retains its value between calls
At the function level, visible only in this file [1]