c-MISRA冲突12.9一元减号的操作数是无符号的



我目前正在处理一些MISRA问题,因此试图理解C.中的整数转换规则

我违反了MISRA-C 2004规则12.9一元减号运算符不应应用于基础类型为无符号的表达式

在代码行中

signed long int test = -1;

我知道不存在负整数常数"-1",而是应用于整数常数"1"的一元负号(如https://en.cppreference.com/w/c/language/integer_constant)。

然而,整数常数"1"是列表中的第一种类型intlong intunsigned long int(直到C99(long int

我使用Keil(ARM 32位(和--c99标志集,而MISRA-C 2004似乎是基于C90标准的。

因此,我的SCA工具似乎假设"1"常量的类型为unsigned long int(直到C99(,但我不明白为什么它不适合普通的int并因此被签名。

为了满足SCA工具的要求,必须对进行编码

signed long int test = -1L;

signed long int test = -((signed long int) 1);

这是正确的行为还是我遗漏了什么?

然而,整数常量"1"是列表int、long int、unsigned long int中的第一种类型。…

正确。像1这样的整数常量的类型是int,就MISRA-C而言,底层类型也是int。定义为(MISRA-C:2004 6.10.4(

术语"基础类型"被定义为描述如果不是由于积分提升的影响,则从评估表达式中获得的类型。

线路signed long int test = -1;符合MISRA-C:2004(和MISRA-C:2012(。

  • 表达式-1本身不包含任何隐含的提升。整体促销不适用
  • 因此,-1具有带符号的底层类型int,并且在赋值时,它被隐式转换为具有相同有符号性的更宽整数类型,这很好
  • 其目的是创建一个带符号的变量,因此关于u后缀的规则不适用
  • 此外,禁止从所谓的"复杂表达式"隐式转换为不同类型的规则10.1也不适用,因为-1是常数表达式,而不是复杂表达式(见MISRA-C:2004 6.10.5(

所以这是另一个工具错误。该工具似乎选择了错误的表达式底层类型,这将是一个严重的错误。

signed long int test = -1L;不是合规性所必需的,尽管它也是合规性代码。

最新更新