On OSX, why does /usr/bin/cpp not support stringification of macro arguments while gcc -E and clang -E do?

StackOverflow https://stackoverflow.com/questions/9508159

  •  14-11-2019
  •  | 
  •  

문제

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top