Search code examples
gcccommand-line-argumentsnamingccmnemonics

What does gcc -E option stand for?


According to gcc manual, the -E option only preprocesses the .c source file, without running the compiler and just giving an input file (.i). But what does the -E stand for?


Solution

  • Summary

    • This option was introduced on compilers much earlier than GCC, and GCC used the same naming for compatibility.

    • My best guess from the historical evidence is that -E stands for "expand macros".

    • The authors of those earlier compilers couldn't call it -P because there was already a -P option, which also ran only the preprocessor, but wrote the output to .i files instead of to standard output. -p was also taken.

    • Over time, -E became preferred to -P, and when GCC was written, it supported only -E and not -P.


    Despite being supposedly off topic for Stack Overflow, I think a bit of history will help explain how this option got its name.

    gcc(1) inherited its basic command line options from much earlier Unix C compilers. Many versions can be found in the Unix Tree archive.

    It looks like the first version that supported -E was Research Unix V7, circa 1979: cc(1) source, man page source. There was also a -P option that also just ran the preprocessor, but sent the result to a file foo.i instead of to standard output. V6 had already supported -P but not -E: cc(1) source, man page source.

    This at least answers why -E wasn't named -P instead: because -P was already in use. (And -p was also taken, it was used to request profiling.) The only hint I found as to why -E was chosen is that the corresponding flag variable in the source code is named exflag. I would hazard a guess that this stands for "expand", as what -E does is basically to expand macros.

    It appears that -P was eventually deprecated in favor of -E. V8 still supported it, but omitted it from the man page. V10 (circa 1989) included two versions of the compiler, cc which compiled traditional C, and lcc for ANSI C. The man page says that cc supports -P with the preprocessor behavior, but for lcc, -P did something else ("write declarations for all defined globals on standard error"). They both supported -E. On other fronts, 32V and BSD, at least initially, supported both, but -P would emit a warning that it was obsolete and -E should be used instead.

    It looks like gcc, from its earliest version, only supported -E and not -P. Since then, a -P option has been introduced, but it does something else ("inhibit generation of linemarkers").