仅评估宏参数一次

时间:2017-04-21 17:47:42

标签: c c89

我需要编写一个宏来捕获任何无效索引 i 以获取长度 n 的数组。这是我到目前为止所得到的:

react

然而,这个定义的问题是索引表达式 i 被评估两次;在表达式 a [ TRAP f (), n )]中,例如 f 可能有副作用或需要很长时间才能执行。我不能引入临时变量,因为宏需要扩展为表达式。此外,将 TRAP 定义为普通函数意味着运行时开销,并使编译器更难以优化陷阱。

有没有办法重写 TRAP 以便 i 只评估一次?

编辑:我使用的是ANSI C89

2 个答案:

答案 0 :(得分:1)

您可以评估一次,并使用结果,通过执行以下操作:

#define TRAP2(i, n) ({unsigned int _i = (i); _i < (n)? _i: (abort(), 0);})

这是一个gcc特定解决方案,在用作任务的RHS时将进行编译。它定义了一个(非常)局部变量,它可能隐藏另一个变量的先前定义,但这并不重要,只要您不尝试在宏中使用先前版本。但正如人们所说,为什么这首先出现呢?

答案 1 :(得分:0)

当索引表达式不包含函数调用时使用宏 TRAP ,并使用(非宏)函数陷阱。这样,函数调用开销仅发生在较罕见的后一种情况中。