对于以下程序:
int main(void)
{
int value = 2;
int result = value >> 1U;
return result;
}
…夹板3.1.2给出警告:
splint_test.c: (in function main)
splint_test.c:4:18: Variable result initialized to type unsigned int, expects
int: value >> 1U
To ignore signs in type comparisons use +ignoresigns
splint似乎声称有符号整数右移的表达式具有无符号整数的类型。但是,我在ANSI C90标准中只能找到:
E1 >> E2
的结果是E1
右移E2
位。如果E1
具有无符号类型,或者E1
具有有符号类型和非负值,则结果的值是E1
的商除以2的幂的整数部分。这段代码的主要目标是一个带有most-c90编译器的嵌入式系统。不过,我对编写符合标准的代码很感兴趣。我已经在c99模式下测试了gcc和clang,这样
E2
就可以工作了。我的问题是:
C标准对位偏移的结果类型有什么要求吗?
编译器吗?
如果不是,为什么斯普林特会发出这个警告?
最佳答案
不。标准规定位移的类型是左操作数的类型,提升为:
6.5.7p3
…结果的类型是提升的左操作数的类型。…
您的工具一定很混乱,用通常的算术转换来推断类型,这种转换适用于大多数二进制运算符,但不适用于<<
和>>
。
还可以通过插入基于_Generic
的类型断言并观察that compilers accept it来验证类型是否为int:
int main(void)
{
int value = 2;
int result = _Generic(value >> 1U, int: value>>1U); //compiles, the type is int
return result;
}