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

标签 c integer implicit-conversion misra

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

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

在代码行中

signed long int test = -1;

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

然而,整数常量“1”是列表中的第一种类型 int、long int、unsigned 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);

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

最佳答案

The integer constant "1" however is of the first type in the list int, long int, unsigned long int...



正确的。整数常量,如 1属于 int 类型就MISRA-C而言,底层类型也是int .定义是 (MISRA-C:2004 6.10.4)

The term "underlying type" is defined as describing the type that would be obtained from evaluating an expression if it were not for the effects of integral promotion.



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

    关于c - MISRA 违规 12.9 一元减号的操作数未签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60989517/

    相关文章:

    c - 将 int 传递给 C 回调

    python - 不进行整数输入

    c++ - 在表达式 bool << integer 中,bool 是提升为 int,还是提升为与整数相同的类型?

    Scala 隐式转换和参数

    parsing - Scala 解析器和隐式有序转换

    c++ - 如果在编译时它的大小未知,是否可以在堆栈上创建一个数组?

    c - 使用 "mmap"从文件读取时得到空输出

    c - 我传递指针参数的方式有什么问题吗?

    python - 为什么 Firestore 对 64 位整数进行舍入?

    Java限制长度整数