我想为二进制旋转创建宏。
我的目标是使这些宏对uint32_tuint64_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))))


我知道编译器抱怨XN类型之间可能不匹配。但是即使我同时投射XN也会产生警告:

ROTL((uint32_t)0xdeadbeef, (uint32_t)0U);


我该怎么做才能以正确的方式摆脱这些警告?

最佳答案

当第二个参数为零或大于第一个参数的位数时,您会遇到一些问题。您可以尝试使用该模块摆脱此问题。这个简单的例子似乎可行:

#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <limits.h>

#define ROTL(X, N) \
    (((X) << ((N) % (CHAR_BIT * sizeof(X)))) | \
     ((X) >> ((CHAR_BIT * sizeof(X) - (N)) % (CHAR_BIT * sizeof(X)))))

int main() {
    for (int i = 0; i < 100; i++) {
        uint32_t a = ROTL(UINT32_C(0xdeadbeef), i);
        printf("%d\t%"PRIX32"\n", i, a);
    }
    return 0;
}


我使用了CHAR_BITlimits.hUINT32_CPRIX32inttypes.h。您可以自行调整ROTR以执行相同的操作。

09-05 00:33