【问题标题】:Macro expansion of __typeof__ to function name__typeof__ 到函数名的宏扩展
【发布时间】:2013-07-27 00:46:16
【问题描述】:

我用纯 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;
}

在这里,我希望将宏 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 Mountain Lion,但我最感兴趣的是让它在任何 POSIX 平台上运行。

【问题讨论】:

    标签: c macros posix c-preprocessor typeof


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      宏扩展发生在 C 标记分析之前(请参阅https://stackoverflow.com/a/1479972/1583175 了解翻译阶段的图表)

      宏预处理器不知道类型信息——它只进行文本处理

      【讨论】:

        【解决方案3】:

        预处理器对类型一无所知,只知道文本标记。 __typeof__() 在预处理器完成宏替换后由编译器通过评估。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-16
          • 2016-01-14
          • 1970-01-01
          相关资源
          最近更新 更多