1

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?

pmor
  • 5,392
  • 4
  • 17
  • 36
  • It's not clear to me what you're asking: can you explain (perhaps give examples) of what you want to allow and what you want to disallow? – Paul Hankin May 19 '21 at 08:59
  • 1
    I think you're saying that you want to allow any compiler to preprocess the file, but only allow compilation with your own compiler (which defines `__MY_CC__`). Perhaps you can do that by adding something that allows preprocessing to continue, but doesn't compile if `__MY_CC__` isn't defined. For example: `#if ! __MY_CC__ "compiler not supported" #endif` – Paul Hankin May 19 '21 at 09:04
  • @PaulHankin Interesting approach, thanks! – pmor May 19 '21 at 09:15
  • @PaulHankin `#if ! __MY_CC__` then after `cc -E` the preprocessing translation unit is expected to not contain `compiler not supported` (because `cc -E` _is_ supported). Is there a way to achieve that? – pmor May 19 '21 at 09:29
  • There is no portable way. – 0___________ May 19 '21 at 09:52
  • 2
    Sorry, but I don't understand what you're asking. Perhaps you can add the underlying problem you're trying to solve and concrete examples of what you want to allow and disallow in the question? – Paul Hankin May 19 '21 at 09:52
  • "`cc -E` is supported" doesn't mean much. What specific use do you have for allowing a file to be preprocessed by an arbitrary compiler but not compiled by it? Why do you want to restrict compilation to _`_MY_CC__`? What are the actual constraints you are under? – Paul Hankin May 19 '21 at 09:54
  • @PaulHankin Added UPD. – pmor May 20 '21 at 08:39
  • 1
    Would it be cheating to define `__MY_CC__` for other compilers via. command line options if/when they're being used to preprocess only (e.g. the `-D__MY_CC__ -E` command line options for clang, gcc, etc); or to introduce another macro (e.g. `#ifdef PREPROCESSING`) and use `-DPREPROCESSING -E` command line options for all compilers when they're preprocessing? – Brendan May 20 '21 at 11:30
  • 1
    To me it looks like the cleanest solution is to add some intermediate meta stage, e.g. the way QT does it. Also Python and libclang seem to be handy here. Not sure if that is going to be helpful https://stackoverflow.com/a/18132250/4885321 – alagner May 21 '21 at 07:18
  • @Brendan The `-D__MY_CC__ -E` approach looks good (here it is not cheating). Thanks! – pmor May 24 '21 at 17:44

1 Answers1

2

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.

rici
  • 234,347
  • 28
  • 237
  • 341