Ritchie
other array, plus the convention that a null character terminates a string. It is interesting to compare
C’s approach with that of two nearly contemporaneous languages, Algol 68 and Pascal [Jensen
74]. Arrays in Algol 68 either have fixed bounds, or are ‘flexible:’ considerable mechanism
is required both in the language definition, and in compilers, to accommodate flexible arrays (and
not all compilers fully implement them.) Original Pascal had only fixedsized
arrays and strings,
and this proved confining [Kernighan 81]. Later, this was partially fixed, though the resulting
language is not yet universally available.
C treats strings as arrays of characters conventionally terminated by a marker. Aside from
one special rule about initialization by string literals, the semantics of strings are fully subsumed
by more general rules governing all arrays, and as a result the language is simpler to describe and
to translate than one incorporating the string as a unique data type. Some costs accrue from its
approach: certain string operations are more expensive than in other designs because application
code or a library routine must occasionally search for the end of a string, because few builtin
operations are available, and because the burden of storage management for strings falls more
heavily on the user. Nevertheless, C’s approach to strings works well.
On the other hand, C’s treatment of arrays in general (not just strings) has unfortunate
implications both for optimization and for future extensions. The prevalence of pointers in C programs,
whether those declared explicitly or arising from arrays, means that optimizers must be
cautious, and must use careful dataflow techniques to achieve good results. Sophisticated compilers
can understand what most pointers can possibly change, but some important usages remain
difficult to analyze. For example, functions with pointer arguments derived from arrays are hard
to compile into efficient code on vector machines, because it is seldom possible to determine that
one argument pointer does not overlap data also referred to by another argument, or accessible
externally. More fundamentally, the definition of C so specifically describes the semantics of
arrays that changes or extensions treating arrays as more primitive objects, and permitting operations
on them as wholes, become hard to fit into the existing language. Even extensions to permit
the declaration and use of multidimensional arrays whose size is determined dynamically are not
entirely straightforward [MacDonald 89] [Ritchie 90], although they would make it much easier
to write numerical libraries in C. Thus, C covers the most important uses of strings and arrays
arising in practice by a uniform and simple mechanism, but leaves problems for highly efficient
implementations and for extensions.
Many smaller infelicities exist in the language and its description besides those discussed
above, of course. There are also general criticisms to be lodged that transcend detailed points.
Chief among these is that the language and its generallyexpected
environment provide little help
for writing very large systems. The naming structure provides only two main levels, ‘external’
(visible everywhere) and ‘internal’ (within a single procedure). An intermediate level of visibility
(within a single file of data and procedures) is weakly tied to the language definition. Thus, there
is little direct support for modularization, and project designers are forced to create their own conventions.
Similarly, C itself provides two durations of storage: ‘automatic’ objects that exist while
control resides in or below a procedure, and ‘static,’ existing throughout execution of a program.
Offstack,
dynamicallyallocated
storage is provided only by a library routine and the burden of
managing it is placed on the programmer: C is hostile to automatic garbage collection.
Whence Success?
C has become successful to an extent far surpassing any early expectations. What qualities
contributed to its widespread use?
Doubtless the success of Unix itself was the most important factor; it made the language
available to hundreds of thousands of people. Conversely, of course, Unix’s use of C and its consequent
portability to a wide variety of machines was important in the system’s success. But the
language’s invasion of other environments suggests more fundamental merits.
Despite some aspects mysterious to the beginner and occasionally even to the adept, C
No comments:
Post a Comment
THE WORLD NEW TECHNOLOGY