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

Is there an equivalent of Haskell's `let`/`in` in C Preprocessor Macros?

我有一个函数如下(用在素数中,以防你好奇)

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

(此代码将是 运行 字面上的数十亿甚至数万亿次,因此性能至关重要)

它不是标准的,但 GCC(以及所有其他模拟它的编译器,即除了 MSVC 之外的几乎所有编译器)支持一个叫做 "statement expressions" 的东西。结合一个可能的typeof,可以让宏变得非常强大。

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

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

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

不能简单...

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