-32768不符合16位有符号值

时间:2014-10-15 05:50:40

标签: c

我正在使用PCLint v 9.00h

在我的代码中,我有以下内容(其中S16是带符号的16位):

S16 temperatureResult = -32768;

除非我的大脑停止工作,否则这个最小值可以适合这种类型

但是我得到一个lint错误"违反MISRA 2004要求规则10.1,将整数隐式转换为较小类型"

如果我将值更改为-32767,则可以正常工作。

我错过了一些明显的东西吗?

4 个答案:

答案 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]所以你无法实现你的目标试图做。