__typeof__宏扩展为函数名

gia*_*uca 5 c macros posix typeof c-preprocessor

我在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;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我希望将宏plus扩展为包含参数类型的函数名.在这个例子中,我希望它扩展以下方式

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)
Run Code Online (Sandbox Code Playgroud)

但是我从预处理器得到的只是

double r = plus___typeof__(x)___typeof(y)(x,y)
Run Code Online (Sandbox Code Playgroud)

而gcc显然会拒绝编译.现在,我知道typeof在编译时进行评估,并且我的理解是,只有在第二个宏包含直接涉及stringify #和连接##标记的宏时,才会阻止对宏进行求值(这就是为什么我cat在你看到的方式).如果这是正确的,__typeof__(x)那么预处理器为什么不评估加倍?在我看来,在构建时应该非常清楚这种行为.甚至在进去之前不应该__typeof__(x)评估?double_cat

我搜索和搜索但我找不到任何东西......我做的事真的很蠢吗?

我正在运行Mac OS X Mountain Lion,但我最感兴趣的是它可以在任何POSIX平台上运行.

ale*_*xsh 6

这不起作用的原因是typeof不是宏而是gcc的C方言中的保留字,因此预处理器完成其工作之后处理.一个很好的类比是sizeof运算符,它既不是宏也不是由预处理器扩展.要做(大约)你想要的(根据参数的类型选择不同的函数)尝试_Generic构造(C11中的新)