我需要一个可以在编译时进行评估的宏,例如:
#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 \
Run Code Online (Sandbox Code Playgroud)
所以代码
#define S1 FIND_RANGE(7)
unsinged int i = S1;
Run Code Online (Sandbox Code Playgroud)
将被发送到编译器
unsinged int i = 8;
Run Code Online (Sandbox Code Playgroud)
是否可以完成这个简单的算法,以便在编译时进行评估?
虽然C没有constexpr
函数,但GCC和Clang都可以在编译时评估简单函数-O1
.相关的优化称为常数折叠.
以下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;
}
Run Code Online (Sandbox Code Playgroud)
结果到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
Run Code Online (Sandbox Code Playgroud)
如您所见,调用findRange
由值替代,该值在编译时计算.
即使findRange
被定义为具有外部链接的正常(非内联)函数,这也可以工作.