运行一次调节的宏

时间:2015-04-28 20:54:11

标签: c if-statement macros conditional

我正在尝试构建一个只运行一次代码的宏。 非常有用,例如,如果你循环一个代码并希望内部只发生一次。易于使用的方法:

static int checksum;

for( ; ; )
{
    if(checksum == 0) { checksum == 1; // ... }
}

但这有点浪费和混乱。所以我有这些宏使用检查位而不是检查变量的真/假状态:

#define CHECKSUM(d) static d checksum_boolean
#define CHECKSUM_IF(x) if( ~(checksum_boolean >> x) & 1) \
                    {                                               \
                        checksum_boolean |= 1 << x;
#define CHECKSUM_END }1

最后的1是强制用户在结尾放置分号。在我的编译器中,这是允许的。

问题是如何在不让用户指定x n 位来检查)的情况下确定如何执行此操作。 所以他可以用这个:

CHECKSUM(char); // 7 run-once codes can be used

for( ; ; )
{
    CHECKSUM_IF
        // code..
    CHECKSUM_END;
}

想法如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

我想你是说你想让宏以某种方式自动跟踪你的位掩码的哪一位包含当前测试的标志。你可以这样做:

#define CHECKSUM(d) static d checksum_boolean; \
    d checksum_mask
#define CHECKSUM_START do { checksum_mask = 1; } while (0)
#define CHECKSUM_IF do {                       \
    if (!(checksum_boolean & checksum_mask)) { \
        checksum_boolean |= checksum_mask;
#define CHECKSUM_END                           \
    }                                          \
    checksum_mask <<= 1;                       \
} while (0)
#define CHECKSUM_RESET(i) do { checksum_boolean &= ~((uintmax_t) 1 << (i)); } while (0)

你可以这样使用:

CHECKSUM(char); // 7 run-once codes can be used

for( ; ; )
{
    CHECKSUM_START;
    CHECKSUM_IF
        // code..
    CHECKSUM_END;
    CHECKSUM_IF
        // other code..
    CHECKSUM_END;
}

但请注意,严重限制

  • CHECKSUM_START宏和所有相应的CHECKSUM_IF宏必须全部显示在同一范围内
  • 在任何CHECKSUM_START阻止
  • 之前,控件必须始终通过CHECKSUM_IF
  • 控件必须始终以相同的顺序到达CHECKSUM_IF块。如果它也跳过使用相同校验和位掩码的所有后续块,它可能只跳过CHECKSUM_IF块。

出现这些限制因为预处理器无法计数。

换句话说,除非重新定义宏,否则没有任何参数的宏总是会扩展为完全相同的文本。因此,如果您不使用宏参数来指示在每种情况下应用哪个标志位,那么需要在运行时跟踪它。