C预处理器宏可以生成函数吗?

时间:2014-10-02 08:29:27

标签: c c-preprocessor c99

是否可以编写一个从此调用生成的宏

WATCH(l1=g1+g2*g3)

这段代码?

TRACE(g1);
TRACE(g2);
TRACE(g3);
l1=g1+g2*g3;
TRACE(l1);

我不确定这是否可行,如果是,请指出我正确的方向。

使用的软件:arm-linux-gnu-gcc,版本4.9.1,Target是Cortex-M3板,语言是C99

的问候, memic

4 个答案:

答案 0 :(得分:0)

没有。该宏将以#define WATCH(X) ...开头,您无法在预处理器中解析X

答案 1 :(得分:0)

这并不容易(而且你提出的方式可能不太可能)。也许你想要一些aspect-oriented programming

考虑使用其他预处理器(例如GPPm4)和/或通过您编写的某些专门程序或脚本生成C ++代码。

您还可以使用GCC自定义MELT编译器(至少在Linux上,使用最近的gccg++)。这需要了解GCC内部结构(特别是Gimple表示),并在MELT中写入另外一个优化过程,该过程将进行转换(可能需要几周的工作)。

答案 2 :(得分:0)

单独使用预处理器是不可能的,但是可以通过表达式模板等一些TMP技巧实现,例如,您可以查看Catch库:

TEST_CASE( "Factorials are computed", "[factorial]" ) {
    REQUIRE( Factorial(0) == 1 );
    REQUIRE( Factorial(1) == 1 );
    REQUIRE( Factorial(2) == 2 );
    REQUIRE( Factorial(3) == 6 );
    REQUIRE( Factorial(10) == 3628800 );
}

这可以产生如下信息:

Example.cpp:9: FAILED:
  REQUIRE( Factorial(0) == 1 )
with expansion:
  0 == 1

请注意最后一行0 == 1,它如何告诉lhs为0,rhs为1,运算符为== ?,嗯,它& #39;通过表达式模板完成,与宏的组合使其易于使用。

答案 3 :(得分:0)

宏调用中的运算符不可能(afaics)。但您可以使用签名函数定义宏:

#define WATCH(l1,g1,g2,g3) \
TRACE(g1); \
TRACE(g2); \
TRACE(g3); \
l1=g1+g2*g3; \
TRACE(l1) 

这会有帮助吗?和复合语句一样,我建议将它们包装在do ... while循环中,比如

#define WATCH(l1,g1,g2,g3) \
do { \
    TRACE(g1); \
    TRACE(g2); \
    TRACE(g3); \
    l1=g1+g2*g3; \
    TRACE(l1); \
} while(0)

这样它的行为就像一个命令;想象

if( condition )  WATCH(l1,g1,g2,g3);

使用未受保护的复合声明。