Note that //
is not a valid C90 comment. It was introduced in C99, so make sure your compiler and pre-processor know they're to use the C99 standard. In many that's -std=c99
. (The question was since edited to make that clear)
Next is that I don't believe the pre-processor cares about comments. From the 6.10 of the C99 spec shows the grammar of preprocessor directives and nowhere does it mention comments...
The ANSI C standard makes it clear comments are supposed to be replaced in 2.1.1.2 "Translation Phases" phase 3 (5.1.1.2 in C99). (Drawing from this other answer).
- The source file is decomposed into preprocessing tokens and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment. Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined.
Older tools might not have followed that either because they predate any C standard or they had bugs or they interpreted the standard differently. They've likely retained those bugs/quirks for backwards compatibility. Testing with clang -E -std=c99
vs /usr/bin/cpp -std=c99
confirms this. They behave differently despite being the same compiler under the hood.
$ /usr/bin/cpp --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ clang --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ ls -l /usr/bin/cpp
-rwxr-xr-x 1 root wheel 18240 Dec 10 01:04 /usr/bin/cpp
$ ls -l /usr/bin/clang
-rwxr-xr-x 1 root wheel 18240 Dec 10 01:04 /usr/bin/clang
$ /usr/bin/cpp -std=c99 test.c
# 1 "test.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 330 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "test.c" 2
int foo[1 // hello there];
$ /usr/bin/clang -E -std=c99 test.c
# 1 "test.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 331 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "test.c" 2
int foo[1];
I suspect invoking clang as /usr/bin/cpp
is causing bug/quirk compatibility with the original behavior of cpp
established back when the behavior was unclear.
I guess the lesson here is to use cc -E
rather than cpp
to ensure consistent behavior.