det*_*tly 17 c code-analysis splint bit-shift language-lawyer
对于以下程序:
int main(void)
{
    int value = 2;
    int result = value >> 1U;
    return result;
}
... Splint 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的幂的整数部分E2。
此代码的主要目标是带有大多数C90编译器的嵌入式系统。但是,我对编写符合标准的代码感兴趣。我一直在以C99模式在GCC和Clang上进行测试,因此可以restrict正常工作。
我的问题是:
PSk*_*cik 17
否。标准说,移位的类型是左操作数的类型,提升为: 6.5.7p3
...结果的类型是提升后的左操作数的类型。...
您的工具必须混淆,使用通常的算术转换来推断类型,该算术转换适用于大多数二进制运算符,但不适用于<<and >>。
您还可以通过插入_Generic基于- 类型的断言并观察编译器接受它来验证类型为int :
int main(void)
{
    int value = 2;
    int result = _Generic(value >> 1U, int: value>>1U); //compiles, the type is int
    return result;
}
Rol*_*lig 17
这是夹板中的错误。夹板错误地假定类型e1 << e2为ctype_wider(te1, te2)。正确的类型是just te1。
该bug的代码从这里开始使用相同的代码路径,位运算符一样&,|并且^,以及对于<<与>>运营商。
在实际的错误是在代码的结束,即假设所有这些按位二进制运算符,返回类型为ctype_wider(te1, te2)。
我在Splint的GitHub问题跟踪器上打开了一个错误,引用了这个问题。
| 归档时间: | 
 | 
| 查看次数: | 731 次 | 
| 最近记录: |