C 宏在编译时求值

标签 c c-preprocessor

我需要一个可以在编译时求值的宏,比如:

#define FIND_RANGE(x) \
if x>16 \
32 \
elif x>8 \
16 \
elif x>4 \
8 \
elif x>2 \
4 \
elif x>1 \
2 \
else \
1 \
endif \

所以代码

#define S1 FIND_RANGE(7)
unsinged int i = S1;

将作为

发送给编译器
unsinged int i = 8;

这个简单的算法可以在编译时进行评估吗?

最佳答案

虽然 C 没有 constexpr 函数,但 GCC 和 Clang 都可以在编译时使用 -O1 计算简单函数。相关优化称为 constant folding .

以下 C 代码:

#include <stdio.h>

static inline unsigned int findRange(unsigned int x)
{
    if (x > 16)
        return 32;
    else if (x > 8)
        return 16;
    else if (x > 4)
        return 8;
    else if (x > 2)
        return 4;
    else if (x > 1)
        return 2;
    return 1;
}

int main(void)
{
    unsigned int i = findRange(7);
    printf("%u\n", i);
    return 0;
}

结果为 x86-64 汇编代码(引用:godbolt.org/g/kVYe0u):

main:
        sub     rsp, 8
        mov     esi, 8
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, 0
        add     rsp, 8
        ret

如您所见,对 findRange 的调用由在编译时计算的值代替。

即使 findRange 被定义为具有外部链接的普通(非内联)函数,这仍然有效。

关于C 宏在编译时求值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41738709/

相关文章:

ios - iOS插件中的malloc错误

c - 在给定 n 个点的平面中找到正方形

c - 如何比较 "if"语句中的字符串?

任何人都可以建议一种无需等待按键即可捕获击键的编码方法吗?

c++ - #define 的奇怪行为

c++ - 对宏的唯一可识别调用

c - mongodb 作为循环数据库

c++ - 如何调用包含参数集的笛卡尔积中所有点的宏?

sql - 如何配置 CMake 目标或命令来预处理 C 文件?

c - 使用 -D 引用宏预处理器