Kay Kay - 1 month ago 14
C Question

static_if in C99's preprocessor

Is it possible to implement static_if in C99?

#define STATIC_IF(COND, ...) \
if (COND) MACRO1(__VA_ARGS__); \
else MACRO2(__VA_ARGS__);


How can I properly implement
STATIC_IF(…)
in here? Depending on
COND
the arguments either should be passed to
MACRO1
or
MACRO2
, but the arguments for both macros look differently.
COND
is statically testable, something like
sizeof (…) > 42
.


  • #if COND
    then
    #define STATIC_IF MACRO1
    … wouldn't work for my use case.

  • I cannot use compiler specific solutions.


Answer

This is not possible, because a condition like sizeof(something)>42 is not static for the preprocessor. The preprocessor is purely textual (in principle, except for arithmetic). It does not know about C or types.

Notice that expression of the condition in #if is severely constrained.

However, you could use build tricks. For instance, you might have a standalone program like

 // generate-sizeof.c
 #include <stdio.h>
 #include "foo-header.h"

 int main(int argc, char**argv) {
    const char* headername = NULL;
    if (argc<2) 
      { fprintf(stderr, "%s: missing header name\n", argv[0]); 
        exit(EXIT_FAILURE); };
    headername = argv[1]; 
    FILE *fh = fopen(headername, "w");
    if (!fh) { perror(headername); exit(EXIT_FAILURE); };
    fprintf(fp, "// generated file %s\n", headername);
    fprintf(fp, "#define SIZEOF_charptr %d\n", (int) sizeof(char*));
    fprintf(fp, "#define SIZEOF_Foo %d\n", (int) sizeof(Foo));
    fclose (fp);
 }

then have a rule like

 generated-sizes.h : generate-sizeof foo-header.h
     ./generate-sizeof generated-sizes.h

in your Makefile etc etc...

So your build machinery will generate the appropriate headers.

Things become much tricker if you want to cross-compile!

Then you might have an #include "generated-sizes.h" in your header, and later code

#if SIZEOF_Foo > 42
#error cannot have such big Foo
#endif
Comments