MISRA 违规 12.9 一元减号的操作数未签名

Rob*_*pha 4 c integer misra implicit-conversion

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

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

在代码行中

signed long int test = -1;
Run Code Online (Sandbox Code Playgroud)

我知道没有负整数常量“-1”,而是应用于整数常量“1”的一元减号(如https://en.cppreference.com/w/c/language/integer_constant 中所述)。

然而整数常量 "1" 是列表中的第一种类型int , long int , unsigned long int (until C99) , long long int (since C99)

我正在遵守 Keil(ARM 32 位)和 --c99 标志集,而 MISRA-C 2004 似乎基于 C90 标准。

所以看起来我的 SCA 工具假设 "1" 常量是unsigned long int (until C99) 类型,但我看不出,为什么它不适合普通int并因此被签名。

为了满足 SCA 工具,必须编写代码

signed long int test = -1L;
Run Code Online (Sandbox Code Playgroud)

或者

signed long int test = -((signed long int) 1);
Run Code Online (Sandbox Code Playgroud)

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

Lun*_*din 5

然而,整数常量“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; 不是合规所必需的,尽管它也是合规代码。