On OSX, why does /usr/bin/cpp not support stringification of macro arguments while gcc -E and clang -E do?
문제
If I have the following code in foo.c
#define P(x) printf("%s\n", #x)
void main() {
P(3 == 4);
}
Invoking gcc -E foo.c will output:
int main() {
printf("%s\n", "3 == 4");
}
Notice that the # operator has stringified the literal for macro argument x. However, when I invoke /usr/bin/cpp, I get the following ... which is not expanded properly.
int main() {
printf("%s\n", #3 == 4);
}
해결책
It looks like for some reason, the cpp
on Lion (I have the same version as you) behaves as though the -traditional
switch is enabled. I can reproduce the output you observed on other cpp
binaries (Linux, FreeBSD), but only when using the -traditional
switch.
After investigating this, it turns out that /usr/bin/cpp
on Mac OS X is a script that starts out like this:
#!/bin/sh
#
# Transitional front end to CCCP to make it behave like (Reiser) CCP:
# specifies -traditional
# doesn't search gcc-include
There is apparently no way to undo -traditional
with another option once it is specified by this script. One workaround is to use a specific installed version, such as cpp-4.2
. Using cpp-4.2
on my system produces the desired expansion.
다른 팁
The cpp
command is probably not behaving as a conformant C preprocessor but as a legacy pre-ANSI C preprocessor. My guess is that Apple made it work that way because Darwin is a BSD system and some broken legacy BSD software using the cpp
command for non-C purposes (like macro processing for config files) would break in subtle ways if you dropped in a conformant C preprocessor in its place.
In any case, the cpp
command should not be used since you never know what you'll get. c99 -E
is the POSIX conformant way to invoke the C preprocessor, and $CC -E
is probably the right way to do it in a Makefile.