c - 位扫描转发作为 C 的编译时常量?
问题描述
bit-scan-forward 函数扫描第一位,例如:
assert(13 == __builtin_ctz(1 << 13));
给定一个在编译时已知的枚举,如何将 GCC__builtin_ctz
或 MSVC 的结果_BitScanForward64
作为编译时常量访问?
解决方案
发布答案,因为这可以通过对所有标志的详尽测试来实现。
此 Python 脚本定义BITSCAN_FTD_CONSTEXPR
了一个适用于 32 位整数的宏,如果没有任何值匹配,则无法编译。
BITS = 32
parens = []
print("#define BITSCAN_FTD_CONSTEXPR_IMPL(a) \\")
for i in range(0, BITS + 1):
print(" ((a) & (1u << %du) ? %d : \\" % (i, i))
print(" 0", end="")
print(")" * (BITS + 1))
print(r'''
#define BITSCAN_FTD_CONSTEXPR(a) \
((sizeof(struct { int _isnt_zero : BITSCAN_FTD_CONSTEXPR_IMPL(a); }) ? \
BITSCAN_FTD_CONSTEXPR_IMPL(a) : \
0 /* Unreachable! */ ))''')
#define BITSCAN_FTD_CONSTEXPR_IMPL(a) \
((a) & (1u << 0u) ? 0 : \
((a) & (1u << 1u) ? 1 : \
((a) & (1u << 2u) ? 2 : \
((a) & (1u << 3u) ? 3 : \
((a) & (1u << 4u) ? 4 : \
((a) & (1u << 5u) ? 5 : \
((a) & (1u << 6u) ? 6 : \
((a) & (1u << 7u) ? 7 : \
((a) & (1u << 8u) ? 8 : \
((a) & (1u << 9u) ? 9 : \
((a) & (1u << 10u) ? 10 : \
((a) & (1u << 11u) ? 11 : \
((a) & (1u << 12u) ? 12 : \
((a) & (1u << 13u) ? 13 : \
((a) & (1u << 14u) ? 14 : \
((a) & (1u << 15u) ? 15 : \
((a) & (1u << 16u) ? 16 : \
((a) & (1u << 17u) ? 17 : \
((a) & (1u << 18u) ? 18 : \
((a) & (1u << 19u) ? 19 : \
((a) & (1u << 20u) ? 20 : \
((a) & (1u << 21u) ? 21 : \
((a) & (1u << 22u) ? 22 : \
((a) & (1u << 23u) ? 23 : \
((a) & (1u << 24u) ? 24 : \
((a) & (1u << 25u) ? 25 : \
((a) & (1u << 26u) ? 26 : \
((a) & (1u << 27u) ? 27 : \
((a) & (1u << 28u) ? 28 : \
((a) & (1u << 29u) ? 29 : \
((a) & (1u << 30u) ? 30 : \
((a) & (1u << 31u) ? 31 : \
((a) & (1u << 32u) ? 32 : \
0)))))))))))))))))))))))))))))))))
#define BITSCAN_FTD_CONSTEXPR(a) \
((sizeof(struct { int _isnt_zero : BITSCAN_FTD_CONSTEXPR_IMPL(a); }) ? \
BITSCAN_FTD_CONSTEXPR_IMPL(a) : \
0 /* Unreachable! */ ))
printf("Example: %i\n", BITSCAN_FTD_CONSTEXPR(1 << 12));
打印的Example: 12
.
经测试可与 GCC-11 和 Clang-12 一起使用。
推荐阅读
- regex - "{{_(" 和 ")}}" 之间的 grep 字符串
- java - 使用 PHP 的 exec() 函数运行一个运行 python 程序的 java 程序 - 但是当它到达 python 调用时它会中断
- c# - Dotnet 构建失败:NuGet 在 Linux 中的代理后面
- opencv - 使用 OpenCV 4.2.0 进行立体声整流
- angularjs - angularjs同步执行函数
- node.js - koa-routes 中的 cnx 或 ctx
- function - 如何通过类的构造函数传递函数?
- swift - 使用 `swiftc -emit-object` 构建目标文件也发出 `_main` 实现
- javascript - JavaScript:如何获取子名
- javascript - 反应形式的动态选项值