You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clang-tidy-18 hicpp-signed-bitwise规则出现“使用有符号整数”误报?

问题:Clang-tidy hicpp-signed-bitwise检查的异常报错分析

用户配置了Clang-tidy的hicpp-signed-bitwise检查,开启IgnorePositiveIntegerLiterals选项后,运行无符号整数位运算代码仍收到错误提示。用户理解前两个错误源于8位值的隐式整数提升,但疑惑为何mytypeU32 & 1报错,而mytypeU32 << 2等运算无报错。

配置文件

# .clang-tidy
---
FormatStyle: file
WarningsAsErrors: '*'
Checks: >
  -*,
  hicpp-signed-bitwise,
CheckOptions:
  hicpp-signed-bitwise.IgnorePositiveIntegerLiterals: true

示例代码

#include "stdint.h"
#include "stdio.h"
#include "inttypes.h"

typedef uint8_t  mytypeU8_t;
typedef uint32_t  mytypeU32_t;

int main(void) {
    mytypeU8_t mytypeU8 = 0;
    mytypeU32_t mytypeU32 = 0;
    unsigned char testChar = 0;

    printf("%"PRIu8, testChar & 1);
    printf("%"PRIu8, testChar << 2);
    printf("%"PRIu8, (testChar << 2 ) | (testChar >> 2));

    printf("%"PRIu8, mytypeU8 & 1);
    printf("%"PRIu8, mytypeU8 << 2);
    printf("%"PRIu8, (mytypeU8 << 2 ) | (mytypeU8 >> 2));

    printf("%"PRIu32, mytypeU32 & 1);
    printf("%"PRIu32, mytypeU32 << 2);
    printf("%"PRIu32, (mytypeU32 << 2 ) | (mytypeU32 >> 2));

    return 0;
}

报错信息

test.c:15:22: error: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise,-warnings-as-errors]
   15 |     printf("%"PRIu8, (testChar << 2 ) | (testChar >> 2));
      |                      ^~~~~~~~~~~~~~~~ ~
test.c:19:22: error: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise,-warnings-as-errors]
   19 |     printf("%"PRIu8, (mytypeU8 << 2 ) | (mytypeU8 >> 2));
      |                      ^~~~~~~~~~~~~~~~ ~
test.c:21:35: error: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise,-warnings-as-errors]
   21 |     printf("%"PRIu32, mytypeU32 & 1);
      |                                 ~ ^

原因分析与解决

1. 前两个错误的原因(8位无符号类型的位或运算)

unsigned char和uint8_t这类8位无符号类型,在参与位运算时会触发整数提升:由于int类型能容纳原类型的所有取值,这些8位值会被隐式转换为signed int。

  • testChar << 2和mytypeU8 << 2的结果都是signed int,后续和另一个提升后的signed int执行|运算时,就触发了hicpp-signed-bitwise对有符号操作数位运算的禁止规则,因此报错。

2. mytypeU32 & 1报错但mytypeU32 << 2不报错的核心差异

(1)mytypeU32 << 2不报错的原因

移位操作的检查逻辑核心是被移位的操作数类型:

  • mytypeU32是uint32_t,在32位平台上,uint32_t的取值范围超过signed int的最大值(2^31-1),因此整数提升时会转换为unsigned int而非signed int。
  • 移位位数2是正整数字面量,开启IgnorePositiveIntegerLiterals选项后,检查会忽略有符号字面量作为移位位数的情况,因此不会触发错误。

(2)mytypeU32 & 1报错的原因

二元位运算(&/|/^)的检查逻辑会关注所有操作数的原始类型:

  • mytypeU32是uint32_t(无符号),而字面量1默认是signed int(有符号)。
  • IgnorePositiveIntegerLiterals选项仅适用于两个有符号操作数之间的运算(其中一个是正整数字面量),但这里是无符号和有符号操作数的混合运算,该选项不生效,因此检查触发错误。

解决方法

要消除mytypeU32 & 1的错误,只需将字面量1显式声明为无符号类型:

printf("%"PRIu32, mytypeU32 & 1U);

对于前两个8位类型的位或错误,同样可以通过显式转换为无符号类型来避免整数提升为signed int:

printf("%"PRIu8, (unsigned)(testChar << 2) | (unsigned)(testChar >> 2));

内容的提问来源于stack exchange,提问作者Slav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:04:51