In V6, the C preprocessor is part of cc
, the compiler driver; see the expand()
function in cc.c
. The directory you linked to contains the source code to the two passes of the C compiler, c0
and c1
(and their floating-point variants, fc0
and fc1
), and the optional optimiser, c2
. The passes are driven by cc
, whose source code is available in the s1
directory.
As far as I can tell, the external preprocessor was introduced in V7.
In both cases, the preprocessor can be invoked using cc -P
. The V6 and V7 cc(1)
manpages provide more detail. Dennis M. Ritchie’s The Development of the C Language paper gives this context:
Many other changes occurred around 1972-3, but the most important was the introduction of the preprocessor, partly at the urging of Alan Snyder, but also in recognition of the utility of the the file-inclusion mechanisms available in BCPL and PL/I. Its original version was exceedingly simple, and provided only included files and simple string replacements: #include
and #define
of parameterless macros. Soon thereafter, it was extended, mostly by Mike Lesk and then by John Reiser, to incorporate macros with arguments and conditional compilation. The preprocessor was originally considered an optional adjunct to the language itself. Indeed, for some years, it was not even invoked unless the source program contained a special signal at its beginning. This attitude persisted, and explains both the incomplete integration of the syntax of the preprocessor with the rest of the language and the imprecision of its description in early reference manuals.
The “special signal at its beginning” is #
as the very first character; this test can be seen in V5’s cc.c
(and in V6’s).
(I’m linking to Diomidis Spinellis’ Unix history repo because I’m familiar with it, but the repo you’ve found also has cc
in s1
.)
cpp
tool is only provided for compatibility and you should invoke cc -E on those compilers instead, otherwise some expansions might not succeed properly.