对于以下程序:

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;
}

09-10 01:40
查看更多