位运算符不应作用于有符号整数
10.3.3 ID_bitwiseOperOnSigned
符号位在位运算方面没有逻辑意义,对负数进行位运算往往意味着逻辑错误。
示例:
int foo(signed s, unsigned u) {
return s & u; // Non-compliant
}
int bar(signed s, unsigned u) {
if (s < 0) {
int a = s << u; // Non-compliant, undefined in C and C++11
int b = s >> u; // Non-compliant, implementation-defined
return a + b;
}
return 0;
}
例中参数 s 可以是负数,对负数左移会导致未定义的行为,对负数右移则由实现定义。
又如:
unsigned absolute(signed v) {
signed m = v >> (sizeof(signed) * CHAR_BIT - 1); // Non-compliant
return (v + m) ^ m; // Non-compliant
}
例中函数可以获取有符号整数的绝对值,利用补码的特性通过位运算免去了条件判断,而且在大部分环境中均可正常运行,但这属于特殊的优化措施,应在文档中有所说明,否则会对代码的可移植性造成难以排查的影响。
相关
依据
ISO/IEC 9899:1999 6.5.7(3)-undefined
ISO/IEC 9899:1999 6.5.7(4)-undefined
ISO/IEC 9899:1999 6.5.7(5)-implementation
ISO/IEC 9899:2011 6.5.7(3)-undefined
ISO/IEC 9899:2011 6.5.7(4)-undefined
ISO/IEC 9899:2011 6.5.7(5)-implementation
ISO/IEC 14882:2003 5.8(2)
ISO/IEC 14882:2003 5.8(3)-implementation
ISO/IEC 14882:2011 5.8(2)-undefined
ISO/IEC 14882:2011 5.8(3)-implementation
参考
CWE-682
C++ Core Guidelines ES.101
MISRA C 2004 12.7
MISRA C 2012 10.1
MISRA C++ 2008 5-0-21
SEI CERT INT13-C