cc-preprocessorc11c17

Is there a standard way to check at compile time that file is being preprocessed only?


Context: all the compilers except __MY_CC__ are not supported. However, how to permit only preprocessing with a 3rd-party compiler?

#if     cc -E
/* permit only preprocessing with a 3rd-party compiler */
#elif   ! __MY_CC__
#error  unsupported compiler
#endif

UPD. The underlying problem I'm trying to solve:

  1. Consider source file named t0.c.

  2. Requirements for t0.c:

    a. t0.c is permitted to be compiled using only my_cc compiler. No other compiler is supported (because t0.c contains target-specific code).

    b. t0.c contains some meta information as well. The meta information is available after t0.c was preprocessed.

    c. The meta information will be used in an environment which does not have my_cc compiler. (It means that t0.c is designed not only to be compiled, but to be just preprocessed, i.e. w/o execution of the subsequent translation phases.) So, t0.c needs to be permitted to be preprocessed using any conforming implementation (hereafter called cc), which is not my_cc.

  3. How to satisfy such requirements?

User Paul Hankin proposed the following approach:

#if   ! __MY_CC__
"compiler not supported"
#endif

This code:

  1. Will be compiled with my_cc. Good.
  2. Will not be compiled with cc, because of syntax error (ex. is given for clang):
t0.c:4:1: error: expected identifier or '('
"compiler not supported"
^
1 error generated.

Good.

  1. After being preprocessed using cc -E the resulting translation unit will contain "compiler not supported", which is undesirable, because:

    a. It is expected that the translation unit does not contain any additional overhead (such as strings).

    b. It breaks the requirements: the cc -E is supported.

Not good.

We can change the "compiler not supported" to "compilation using non __MY_CC__ is not supported". However, it is expected that after t0.c was prepossessed the resulting translation unit does not contain any additional overhead (such as strings). Is there any overhead-less solution?


Solution

  • There is no standard way to request "preprocessor-only" compilation. In fact, there is no standard definition of what "preprocessor-only" compilation might do, since the standard (a) does not mandate that preprocessing be a separable module of the compiler and (b) to the extent that the preprocessor phases are defined, mandates that the result after preprocessing phase be a sequence of tokens without whitespace, which is not the same thing as a sequence of characters.

    That being the case, there is certainly no standard way to detect whether a given compiler is doing something non-standard, like fabricating a preprocessed output.

    If you're not actually concerned with 100% portability, you could probably do this most easily with a build script.