【发布时间】:2019-03-07 14:51:17
【问题描述】:
我想为二进制旋转创建宏。
我的目标是使这些宏对uint32_t 和uint64_t 操作数类型都通用。
我来到了这个实现:
#define ROTL(X, N) (((X) << (N)) | ((X) >> (8 * sizeof(X) - (N))))
#define ROTR(X, N) (((X) >> (N)) | ((X) << (8 * sizeof(X) - (N))))
这些宏工作正常,但gcc 编译器在编译期间会产生警告:
warning: right shift count >= width of type [enabled by default]
#define ROTL(X, N) (((X) << (N)) | ((X) >> (8 * sizeof(X) - (N))))
warning: left shift count >= width of type [enabled by default]
#define ROTL(X, N) (((X) << (N)) | ((X) >> (8 * sizeof(X) - (N))))
我知道编译器抱怨X 和N 的类型可能不匹配。但是即使我同时投射X 和N 也会产生警告:
ROTL((uint32_t)0xdeadbeef, (uint32_t)0U);
我该怎么做才能以正确的方式消除这些警告?
【问题讨论】:
-
这在生成的汇编代码方面效率不高。如果您需要速度,您可能想要使用编译器内在函数(很大程度上依赖于平台/编译器)。
-
由于这些宏对每个参数进行两次评估,请注意不要使用具有副作用的参数调用它们。
-
@Jabberwocky:实际上,现在几乎所有的编译器都足够聪明,可以理解宏发生了什么,并用适当的内在函数替换它(参见godbolt.org/z/R7WQgM)。你可以使用 gcc、clang、mcvc 来获得它。
-
您需要显示实际的宏调用,以了解编译器为何向您发出警告。
标签: c gcc macros binary bit-manipulation