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:
Consider source file named t0.c
.
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
.
How to satisfy such requirements?
User Paul Hankin proposed the following approach:
#if ! __MY_CC__
"compiler not supported"
#endif
This code:
my_cc
. Good.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.
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?
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.