Question

I wrote the following code in plain C:

#define _cat(A, B) A ## _ ## B
#define cat(A, B) _cat(A, B)
#define plus(A, B) cat(cat(plus,__typeof__(A)),__typeof__(B))(A, B)

int main(int argc, const char * argv[])
{
    double x = 1, y = 0.5;
    double r = plus(x, y);
    printf("%lf",r);
    return 0;
}

Here, I would like the macro plus to be expanded becoming a function name which contains the types of the parameters. In this example I would like it to expand the following way

double r = plus(x, y)
...
/* First becomes*/
double r = cat(cat(plus,double),double)(x, y)
...
/* Then */
double r = cat(plus_double,double)(x, y)
...
/* And finally */
double r = plus_double_double(x, y)

However all I got from the preprocessor is

double r = plus___typeof__(x)___typeof(y)(x,y)

and gcc will obviously refuse to compile. Now, I know that typeof evaluates at compile-time and it is my understanding that a macro is only prevented from being evaluated when it is contained in second macro which directly involves the stringify #and the concatenation ## tokens (here's the reason why I split cat in the way you see). If this is right, why doesn't __typeof__(x) get evaluated to double by the preprocessor? Seems to me that the behaviour should be perfectly clear at build time. Shouldn't __typeof__(x) evaluate to double before even going in _cat?

I searched and searched but I couldn't find anything... Am I doing something really really stupid?

I'm running Mac OS X Mountain Lion but I'm mostly interested in getting it work on any POSIX platform.

Was it helpful?

Solution

The reason this does not work is typeof is not a macro but a reserved word in the gcc's dialect of C and is thus handled after the preprocessor has finished its work. A good analogy would be the sizeof operator which is not a macro either and is not expanded by the preprocessor. To do (approximately) what you want (pick a different function based on the type of the arguments) try the _Generic construct (new in C11)

OTHER TIPS

Macro expansion occurs before C token analysis (see https://stackoverflow.com/a/1479972/1583175 for a diagram of the phases of translation)

The macro preprocessor is unaware of the type information -- it merely does text processing

The preprocessor knows nothing about types, only about textual tokens. __typeof__() gets evaluated by the compiler pass, after the preprocessor has finished performing macro replacements.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top