Search code examples
clanguage-lawyerc11pragma

How to check the state of #pragma STDC?


Consider this code:

/* t0.c */
#pragma STDC FENV_ACCESS ON
#include "t0.h"

Then in t0.h how to check the state of STDC FENV_ACCESS?

/* t0.h */
/* how to check the state of STDC FENV_ACCESS? */
/* something like: #if STDC FENV_ACCESS == ON */

If not possible, then:

  1. Why not possible?
  2. Will it be useful to add this feature to the C standard?

Solution

  • (1) Why not possible?

    It is possible with a custom cpp as rryker's answer mentioned. Otherwise, I would have said "no" because the compiler uses the pragmas and that comes after the cpp pass/stage.

    (2) Will it be useful to add this feature to the C standard?

    No, probably not. For the above mentioned reason.

    And, because, drawing a leaf from what is already common (e.g. autoconf), we can reverse the problem to get the desired results without changing existing compilers.

    Define (e.g.) a features.h:

    #ifdef STDC_FENV_ACCESS_ON
    #if STDC_FENV_ACCESS_ON
    #pragma STDC FENV_ACCESS ON
    #else
    #pragma STDC FENV_ACCESS OFF
    #endif
    #endif
    

    UPDATE:

    Re: "custom cpp as rryker's answer mentioned": hm, where is the rryker's answer? I don't see it. – pmor

    I wrote that before rryker deleted his answer [partly] because of critique/comments from HolyBlackCat that couldn't be addressed immediately. My inference was rryker would be able to improve his answer and undelete it, so I left up the reference.

    The link rryker based his answer on was specific extensions provided by clang: https://clang.llvm.org/docs/LanguageExtensions.html The features that rryker's answer referred to were: the __has_feature and __has_extension macros [since version 10].

    That's the reference. However, with a bit of conjecture on my part, I'll try to summarize.

    IIRC, clang's cpp is not a separate program that is only loosely connected to the compiler [e.g. like it is with gcc].

    With clang, the preprocessor is a [more] tightly integrated stage within the compiler itself. My presumption is that this was [initially] done for speed and code reuse.

    But, as a "side effect" of that:

    1. clang's cpp can have much more intimate knowledge of the compiler's inner workings.

    2. And, if it's more efficient/desirable, clang's cpp stage could also do more of the early (e.g.) pragma processing.

    3. And, cpp could have access to (e.g.) all the -f* arguments/options the compiler sees.

    4. So, it has all of the tools that make #if/#ifdef on the above __has_* macros feasible.