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

问题描述 投票:-3回答:4

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

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

c c-preprocessor c99
4个回答
0
投票

不会。宏会从#define WATCH(X) ...开始,你无法在预处理器中解析X


0
投票

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

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

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


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,运算符是== ?,好吧,它是通过表达式模板完成的,与宏的组合使它易于使用。


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);

使用未受保护的复合语句。

© www.soinside.com 2019 - 2024. All rights reserved.