在C预处理器宏中是否有相当于Haskell的`let` /`in`?

时间:2015-06-16 05:56:37

标签: c c-preprocessor

我有一个如下功能(如果你好奇的话,用在一个主要的seive中)

unsigned long long primeAt(unsigned long long index) {
    return index * 3 + (index % 2 ? 2 : 1);
}

我已经重构为宏

#define PRIME_AT(index) (index * 3 + (index % 2 ? 2 : 1))

出于性能和可读性的原因。

我想知道是否有任何方法可以为此功能做同样的事情:

unsigned long long indexOf(unsigned long long prime) {
    int mod = prime % 6;
    return prime / 3 - (mod == 0 || mod == 3 || mod == 4);
}

无需重新计算prime % 6 3次,如下所示?

#define INDEX_OF(prime) (prime / 3 - ((prime % 6) == 0 || (prime % 6) == 3 || (prime % 6) == 4));

(如果不是数万亿次,这段代码将以十亿分之一的价格运行,因此性能至关重要)

2 个答案:

答案 0 :(得分:1)

这不是标准的,但是GCC(以及所有其他模拟它的编译器,即除了MSVC之外的所有其他编译器)都支持一种称为“语句表达式”的东西。结合可能的typeof,它可以使宏非常强大。

#define MAX(a, b) ({ __typeof__((a)) __a = (a); typeof((b)) __b = (b); __a > __b ? __a : __b; })

({})块中的最后一个语句必须是表达式语句,它将用作语句表达式的值。

也就是说,如果ab可证明没有副作用,那么即使没有这个,GCC也非常擅长优化重复计算。

答案 1 :(得分:1)

不能简单......

#define INDEX_OF(prime,mod) (prime / 3 - (mod == 0 || mod == 3 || mod == 4));