【问题标题】:C preprocessor macro to generate functions possible?C 预处理器宏生成函数可能吗?
【发布时间】:2014-11-27 05:15:12
【问题描述】:

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

WATCH(l1=g1+g2*g3)

这段代码?

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

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

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

问候, 模因

【问题讨论】:

  • 考虑使用其他预处理器(例如 GPPm4)和/或通过您的专门程序生成 C++ 代码。
  • 避免对复杂的东西使用预处理器。很难调试,而且你没有类型检查的奢侈
  • 我怀疑这是一个 XY 问题。在 C++ 中,我们可能会通过将所有 4 个变量声明为自定义类型来解决 X 问题,以便可以重载其运算符以打印参数。
  • WATCH 是一个宏,我想定义它来生成代码,其中包含其他宏(TRACE)
  • 如果您使用 C99,为什么要使用 C++ 标签?

标签: c c-preprocessor c99


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    这并不容易(而且按照您的要求可能是不可能的)。也许你想要一些aspect-oriented programming

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

    您还可以使用MELT 自定义您的GCC 编译器(至少在Linux 上,使用最近的gccg++)。这需要了解 GCC 内部结构(尤其是 Gimple 表示)并在 MELT 中编写一个额外的优化通道来完成转换(因此可能需要几周的工作)。

    【讨论】:

    • 没听说过 c 语言中的面向方面编程
    • @memic 原来的标签是 c++。
    【解决方案3】:

    单独使用预处理器是不可能的,但是可以使用一些 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,操作符是==?,嗯,是通过表达式模板完成的,组合使用宏只是让它易于使用。

    【讨论】:

    • OP 使用的是 C (C99) - 不知道为什么这个问题被标记为 C++。
    【解决方案4】:

    在宏调用中使用运算符是不可能的(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);
    

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

    【讨论】:

    • 是的,这与 user2501 的建议类似.. thx :) 这里的问题是宏内部的运算符 (+,*) ..
    • 您的意思是WATCH(l1=g1+g2*g3) 形式的调用已经在代码中并且您不能手动更改它们?然后,作为构建的一部分,您需要比 cpp(补丁、sed)更好的文本处理。
    • yes l1+g2+g*g3 是我要执行的代码,并在执行该行之前跟踪右侧的变量和执行该行之后的左侧
    • 哦。你的意思是你想对任意表达式这样做?
    • 是的,没错,但在我看来,没有简单的解决方案
    猜你喜欢
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 2015-07-12
    • 2021-08-19
    • 2020-02-09
    • 2014-04-13
    • 1970-01-01
    • 2018-01-03
    相关资源
    最近更新 更多