"Use of a signed integer operand with a binary bitwise operator" - 使用 unsigned short 时
"Use of a signed integer operand with a binary bitwise operator" - when using unsigned short
在以下检查 16 位序列的前两位是否已设置的 C 代码段中:
bool is_pointer(unsigned short int sequence) {
return (sequence >> 14) == 3;
}
CLion 的 Clang-Tidy 给我一个 "Use of a signed integer operand with a binary bitwise operator" 警告,我不明白为什么。 unsigned short
还不够无符号吗?
The code for this warning 检查按位运算符的 either 操作数是否已签名。引起警告的不是 sequence
,而是 14
,您可以通过在末尾附加 u
使 14
无符号来缓解此问题。
(sequence >> 14u)
这个警告很糟糕。正如 所述,CLion 正在解决此问题。
我认为整数提升会导致这里出现警告。对于带符号的算术表达式,小于 int 的操作数被扩展为整数。所以你的代码实际上是 return ( (int)sequence >> 14)==3;
导致了警告。尝试 return ( (unsigned)sequence >> 14)==3;
或 return (sequence & 0xC000)==0xC000;
.
clang-tidy 中有一个名为 hicpp-signed-bitwise
的检查。此检查遵循 HIC++ 标准的措辞。该标准 is freely available 并表示:
5.6.1. Do not use bitwise operators with signed operands
Use of signed operands with bitwise operators is in some cases subject to undefined or implementation defined behavior. Therefore, bitwise operators should only be used with operands of unsigned integral types.
HIC++ 编码标准的作者误解了 C 和 C++ 标准的意图,无意或有意地关注操作数的 类型 而不是 value 的操作数。
clang-tidy 中的检查正是执行了这个措辞,以符合该标准。该检查是 not intended to be generally useful,它的唯一目的是帮助那些程序必须符合 HIC++ 标准的愚蠢规则的可怜人。
关键点是,根据定义,没有任何后缀的整型文字属于 int
类型,并且该类型被定义为有符号类型。 HIC++ 现在错误地得出正整数文字可能为负的结论,因此可能 调用未定义的行为。
为了比较,C11 标准说:
6.5.7 Bitwise shift operators
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
这个措辞经过精心挑选,强调右操作数的值很重要,而不是它的类型。它还涵盖了值过大的情况,而 HIC++ 标准只是忘记了这种情况。因此,在 HIC++ 中说 1u << 1000u
是可以的,而 1 << 3
则不是。
最好的策略是明确禁用此单一检查。有 several bug reports for CLion 提到了这个,它正在那里得到修复。
2019-12-16 更新:我问 Perforce 这个确切措辞背后的动机是什么,这个措辞是否是故意的。这是他们的回复:
Our C++ team who were involved in creating the HIC++ standard have taken a look at the Stack Overflow question you mentioned.
In short, referring to the object type in the HIC++ rule instead of the value is an intentional choice to allow easier automated checking of the code. The type of an object is always known, while the value is not.
- HIC++ rules in general aim to be "decidable". Enforcing against the type ensures that a decidable check is always possible, ie. directly where the operator is used or where a signed type is converted to unsigned.
- The rationale explicitly refers to "possible" undefined behavior, therefore a sensible implementation can exclude:
- constants unless there is definitely an issue and,
- unsigned types that are promoted to signed types.
- The best operation is therefore for CLion to limit the checking to non-constant types before promotion.
在以下检查 16 位序列的前两位是否已设置的 C 代码段中:
bool is_pointer(unsigned short int sequence) {
return (sequence >> 14) == 3;
}
CLion 的 Clang-Tidy 给我一个 "Use of a signed integer operand with a binary bitwise operator" 警告,我不明白为什么。 unsigned short
还不够无符号吗?
The code for this warning 检查按位运算符的 either 操作数是否已签名。引起警告的不是 sequence
,而是 14
,您可以通过在末尾附加 u
使 14
无符号来缓解此问题。
(sequence >> 14u)
这个警告很糟糕。正如
我认为整数提升会导致这里出现警告。对于带符号的算术表达式,小于 int 的操作数被扩展为整数。所以你的代码实际上是 return ( (int)sequence >> 14)==3;
导致了警告。尝试 return ( (unsigned)sequence >> 14)==3;
或 return (sequence & 0xC000)==0xC000;
.
clang-tidy 中有一个名为 hicpp-signed-bitwise
的检查。此检查遵循 HIC++ 标准的措辞。该标准 is freely available 并表示:
5.6.1. Do not use bitwise operators with signed operands
Use of signed operands with bitwise operators is in some cases subject to undefined or implementation defined behavior. Therefore, bitwise operators should only be used with operands of unsigned integral types.
HIC++ 编码标准的作者误解了 C 和 C++ 标准的意图,无意或有意地关注操作数的 类型 而不是 value 的操作数。
clang-tidy 中的检查正是执行了这个措辞,以符合该标准。该检查是 not intended to be generally useful,它的唯一目的是帮助那些程序必须符合 HIC++ 标准的愚蠢规则的可怜人。
关键点是,根据定义,没有任何后缀的整型文字属于 int
类型,并且该类型被定义为有符号类型。 HIC++ 现在错误地得出正整数文字可能为负的结论,因此可能 调用未定义的行为。
为了比较,C11 标准说:
6.5.7 Bitwise shift operators
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
这个措辞经过精心挑选,强调右操作数的值很重要,而不是它的类型。它还涵盖了值过大的情况,而 HIC++ 标准只是忘记了这种情况。因此,在 HIC++ 中说 1u << 1000u
是可以的,而 1 << 3
则不是。
最好的策略是明确禁用此单一检查。有 several bug reports for CLion 提到了这个,它正在那里得到修复。
2019-12-16 更新:我问 Perforce 这个确切措辞背后的动机是什么,这个措辞是否是故意的。这是他们的回复:
Our C++ team who were involved in creating the HIC++ standard have taken a look at the Stack Overflow question you mentioned.
In short, referring to the object type in the HIC++ rule instead of the value is an intentional choice to allow easier automated checking of the code. The type of an object is always known, while the value is not.
- HIC++ rules in general aim to be "decidable". Enforcing against the type ensures that a decidable check is always possible, ie. directly where the operator is used or where a signed type is converted to unsigned.
- The rationale explicitly refers to "possible" undefined behavior, therefore a sensible implementation can exclude:
- constants unless there is definitely an issue and,
- unsigned types that are promoted to signed types.
- The best operation is therefore for CLion to limit the checking to non-constant types before promotion.