2013-07-27 42 views
3

我写在平原Ç以下代码:__typeof__的宏扩展至功能名称

#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; 
} 

在这里,我想宏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) 

但是,所有我从预处理得到的是

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

和gcc显然会拒绝编译。现在 ,我知道的typeof评估在编译时间,这是我的理解是,宏只从当它被包含在其中直接涉及到字符串化#以及级联##令牌(这里的原因,第二个宏被评价防止为什么我以你看到的方式分割cat)。如果这是正确的,那么为什么__typeof__(x)不会被预处理器评估加倍?在我看来,这个行为在构建时应该非常清楚。在进入_cat之前,不应该__typeof__(x)评估为double

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

我运行Mac OS X山狮,但我得到它的任何POSIX平台上工作最感兴趣。

回答

1

预处理器对类型只知道文本标记。 __typeof__()在预处理器完成执行宏替换后,由编译器通过评估。它仅仅确实文本处理

2

宏扩展前的C令牌分析(见https://stackoverflow.com/a/1479972/1583175用于翻译的相位的示图)

宏预处理器不知道的类型的信息发生不工作是的typeof不是宏但在C的GCC的方言保留字,因此处理后的预处理器已经完成其工作。一个很好的比喻是sizeof算子,它既不是宏,也不是预处理器扩展的。要做(大约)你想要什么(根据参数的类型选择一个不同的函数)尝试_Generic构造(C11新增)