4

我目前正在处理一些 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 long int (C99 起)

我正在使用 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);

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

4

1 回答 1

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;不是合规所必需的,尽管它也是合规代码。

于 2020-04-02T11:16:26.980 回答