我正在使用PCLint v 9.00h
在我的代码中,我有以下内容(其中S16是带符号的16位):
S16 temperatureResult = -32768;
除非我的大脑停止工作,否则这个最小值可以适合这种类型
但是我得到一个lint错误"违反MISRA 2004要求规则10.1,将整数隐式转换为较小类型"
如果我将值更改为-32767,则可以正常工作。
我错过了一些明显的东西吗?
答案 0 :(得分:4)
它不一定"不适合"。很可能它适合。 (你真的检查了吗?)
如果您的平台使用32位(或更大)int
,那么所有算术表达式都将以32位int
类型进行评估,并且警告只会告诉您正在转换int
值为较小的类型。 PCLint根本没有费心去检查实际值是否适合目标类型。
您可以使用显式类型转换来抑制此警告
S16 temperatureResult = (S16) -32768;
如果您的平台使用16位int
,则此处可能会涉及稍微不同的问题。在C语言中,-32768
不是原子常数。 -32768
实际上是一个表达式,由一个应用于正常数-
的一元32768
运算符组成。 32768
是一个不适合16位类型的正常量,因此编译器使用较大的类型(可能是32位long int
)来表示32768
。因此,-32768
在较大类型的域中进行评估,并最终作为较大类型的值。 PCLind决定警告你隐式切换到更大的类型。 (有关详细信息,请参阅(-2147483648> 0) returns true in C++?。)
如果这是在这里发生的事情,那么为了避免警告,您可以使用显式类型转换
S16 temperatureResult = (S16) -32768;
或者,您可以将初始化表示为
S16 temperatureResult = -32767 - 1;
在后一种情况下,编译器应该能够评估16位int
类型域中的常量表达式。
答案 1 :(得分:3)
该标准仅保证签名短期的[-32767,32767]范围。您的实现可能会像大多数实现一样扩展这一点,但PCLint会检查标准符合性。
答案 2 :(得分:3)
首先:它不必按标准处理-32768:
5.2.4.2.1整数类型的大小
[...]
- short int
类型对象的最小值SHRT_MIN -32767 // - (215 - 1)
- short int
类型的对象的最大值SHRT_MAX +32767 // 215 - 1
(我正在寻找关于支持-32768的环境定义说明的部分)
知道了:
本段有理由支持再支持一个号码的原因:
6.2.6.2整数类型
[...]
2 - 对于有符号整数类型,对象表示的位应分为三个 groups:值位,填充位和符号位。不需要任何填充位; 应该只有一个符号位。作为值位的每个位应具有相同的值 相应的无符号类型的对象表示中的相同位(如果有的话) 有符号类型中的M值位和无符号类型中的N,则M <= N)。如果符号位 为零,它不会影响结果值。如果符号位为1,则应以下列方式之一修改该值:
- 符号位0的相应值被否定(符号和幅度);
- 符号位的值为 - (2N)(二进制补码);
- 符号位的值为 - (2N - 1)(1'补码)。
其中哪一个适用于实现定义,以及符号位为1的值 并且所有值位为零(前两个),或者符号位和所有值位1(对于' 补码),是陷阱表示或正常值。在签名和 幅度和1'补码,如果这个表示是一个正常值,它被称为a 负零。
(我所引用的所有内容均采用ISO / IEC 9899:TC3编写)
答案 3 :(得分:1)
想到尝试:
S16 temperatureResult =(S16)0x8000; // ASSUMES二进制补码整数
显式广播是因为Rule 10.1说
“整数类型的表达式的值不应该是隐含的 如果......“
转换为不同的基础类型
让它变得便携:
S16 temperatureResult = -32767 - 1;
但是无论如何,如果MISRA需要与补充计算机(如某些Cray超级计算机)兼容,那么签名16位的保证范围只有[-32767 ... 32767]所以你无法实现你的目标试图做。