Home > Enterprise >  Typechecking in C preprocessor
Typechecking in C preprocessor

Time:06-03

I was hoping to implement optional arguments in c by using macros to set a function based on the variable type.

#define dostuff(BOOL) dostuffwithbool(BOOL)
#define dostuff(INT) dostuffwithint(INT)

Is this kind of thing possible at all? (even though I know it probably isn't). I'd accept any answer no matter how long or hacky.

Also, please don't downvote if it isn't possible. I'm asking this because I'm very new to the syntax of macros and I'm not sure exactly how far they can go.

CodePudding user response:

The preprocessor itself is not capable of processing C types because macros are expanded after tokenization of program but the before syntactical constructs of C language are parsed.

Depending on your application you can use _Generic available from C11. It is basically switch-case over types.

#define dostuff(val)                    \
  _Generic((val), bool: dostuffwithbool \
                , int:  dostuffwithint) (val)

Note that this solution will not work if dostuffwithbool/dostuffwithint were function-like macros. The macros would not be expanded due to a lack of ( following a macro.

CodePudding user response:

You can't do it with just the macro itself, because macro is a placeholder (for the preprocessor) and not a function (subroutine).

The preprocessor replaces all occurrences of a macro with the code you define at the macro's definition. It's the same with numeric defines like #define PI 3.141592654. Here, PI is not a variable. Instead, every occurrence of PI in the code will be replaced with 3.141592654. Same counts for the macros.

So for example this code with a simple comparison macro:

#include <stdio.h>

#define EQUALS(a, b) (a == b ? 1 : 0)

int main()
{
    char nZero = 0;
    char nOne = 1;
    printf("0 is 0: %d\n", EQUALS(nZero, nZero));
    printf("0 is 1: %d\n", EQUALS(nZero, nOne));
    return 0;
}

Will be expanded to the folowing code by the preprocessor:

int main()
{
    char nZero = 0;
    char nOne = 1;
    printf("0 is 0: %d\n", (nZero == nZero ? 1 : 0));
    printf("0 is 1: %d\n", (nZero == nOne ? 1 : 0));
    return 0;
}

Note: Be careful with macros, because they will be expanded exactly the way you write them in their definition. So for example it is good practice to place brackets around calculations, since something like this:

#define ADD(a, b) a   b
int x = a * ADD(b, c);

will be expanded to this:

int x = a * b   c;

and not this:

int x = a * (b   c);
  • Related