简体   繁体   English

-32768不适合16位有符号值

[英]-32768 not fitting into a 16 bit signed value

I am using PCLint v 9.00h 我正在使用PCLint v 9.00h

In my code I have the following (where S16 is a signed 16 bit): 在我的代码中,我有以下内容(其中S16是带符号的16位):

S16 temperatureResult = -32768;

Which unless my brain has stopped working is the smallest value that can fit into this type 除非我的大脑停止工作,否则哪一个值可以适合此类型

But I am getting a lint error of "Violates MISRA 2004 Required Rule 10.1, Implicit conversion of integer to smaller type" 但是,我收到的错误消息是“违反MISRA 2004所需规则10.1,将整数隐式转换为较小类型”

If I change the value to -32767 it works fine. 如果我将值更改为-32767,则可以正常工作。

Am I missing something obvious? 我是否缺少明显的东西?

It doesn't necessarily "not fit". 它不一定“不适合”。 Quite possibly it fits. 很可能适合。 (Did you actually check it?) (您确实检查过吗?)

  • If your platform uses 32-bit (or larger) int , then all arithmetic expressions are evaluated in 32-bit int type and the warning simply tells you that you are converting an int value to a smaller type. 如果您的平台使用32位(或更大) int ,则所有算术表达式都以32位int类型求值,并且警告仅告诉您您正在将int值转换为较小的类型。 PCLint simply didn't bother to check whether the actual value fits into the destination type. PCLint根本不用理会实际值是否适合目标类型。

    You might be able to suppress this warning with an explicit type cast 您可能可以通过显式类型转换来抑制此警告

     S16 temperatureResult = (S16) -32768; 
  • If your platform uses 16-bit int , then a slightly different issue might be involved here. 如果您的平台使用16位int ,那么这里可能涉及到稍微不同的问题。 In C language -32768 is not an atomic constant. 在C语言中-32768不是原子常数。 -32768 is actually an expression consisting of an unary - operator applied to a positive constant 32768 . -32768实际上是由一个一元的表达-应用到一个正的常数算子32768 32768 is a positive constant that does not fit into a 16-bit type, for which reason the compiler uses a larger type (32-bit long int probably) to represent 32768 . 32768是一个不适合16位类型的正常数,因此,编译器使用较大的类型(可能是32位long int )来表示32768 Consequently, -32768 is evaluated in the domain of a larger type and also ends up as a value of larger type. 因此, -32768在较大类型的域中求值,并且最终也变为较大类型的值。 PCLind decided to warn you about the implicit switch to a larger type. PCLind决定警告您有关隐式切换到更大类型的信息。 (See (-2147483648> 0) returns true in C++? for more details.) (有关更多详细信息,请参见(-2147483648> 0)在C ++中返回true 。)

    If that's what's happening here, then to avoid the warning you can use an explicit type cast 如果这是这里发生的事情,那么可以使用显式类型强制转换来避免警告

     S16 temperatureResult = (S16) -32768; 

    or, alternatively, you can express the initialization as 或者,您也可以将初始化表示为

     S16 temperatureResult = -32767 - 1; 

    In the latter case the compiler should be able to evaluate the constant expression within the domain of 16-bit int type. 在后一种情况下,编译器应该能够在16位int类型的域内求值常量表达式。

The standard only guarantees the range of [-32767,32767] for signed short. 该标准仅保证有符号短路的范围为[-32767,32767]。 Your implementation may extend this a bit, like most implementations do, but PCLint checks for standards compliance. 您的实现可能会像大多数实现一样稍微扩展此范围,但是PCLint会检查是否符合标准。

First of all: it doesn't have to deal with -32768 by standard: 首先:按照标准,它不必处理-32768:

5.2.4.2.1 Sizes of integer types 5.2.4.2.1整数类型的大小

[...] [...]

— minimum value for an object of type short int — short int类型的对象的最小值

SHRT_MIN -32767 // -(215 - 1) SHRT_MIN -32767 //-(215-1)

— maximum value for an object of type short int — short int类型的对象的最大值

SHRT_MAX +32767 // 215 - 1 SHRT_MAX +32767 // 215-1

(I'm looking for the part which makes a enviroment defined note about supporting -32768 anyway) (我正在寻找使环境定义的注释无论如何都支持-32768的部分)

Got it: 得到它了:

The reason why there is sometimes anyway one more number supported is justified by this paragraph: 本段说明了有时仍然支持一个数字的原因:

6.2.6.2 Integer types 6.2.6.2整数类型

[...] [...]

2 — For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. 2 —对于有符号整数类型,对象表示的位应分为三组:值位,填充位和符号位。 There need not be any padding bits; 不需要任何填充位; there shall be exactly one sign bit. 必须有一个符号位。 Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M <= N). 作为值位的每一位应具有与对应的无符号类型的对象表示形式中的相同位相同的值(如果有符号类型中有M个值比特,无符号类型中有N个值比特,则M <= N)。 If the sign bit is zero, it shall not affect the resulting value. 如果符号位为零,则它将不影响结果值。 If the sign bit is one, the value shall be modified in one of the following ways: 如果符号位为1,则应通过以下方式之一修改值:

— the corresponding value with sign bit 0 is negated (sign and magnitude); —符号位0的对应值被取反(符号和大小);

— the sign bit has the value -(2N) (two's complement); —符号位的值为-(2N)(二进制补码);

— the sign bit has the value -(2N - 1) (ones' complement). —符号位的值为-(2N-1)(一个补码)。

Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for ones' complement), is a trap representation or a normal value. 其中哪一个是实现定义的,标志位为1且所有值位为零的值(对于前两个)还是标志位且所有值位为1(位的补码)是陷阱表示?或正常值。 In the case of sign and magnitude and ones' complement, if this representation is a normal value it is called a negative zero. 在符号,大小和“ 1”的补码情况下,如果此表示形式是正常值,则称为负零。

(All I'm quoting is written in ISO/IEC 9899:TC3) (我所引用的全部内容均用ISO / IEC 9899:TC3编写)

It comes to mind to try: 想到尝试:

S16 temperatureResult = (S16) 0x8000; S16 temperatureResult =(S16)0x8000; // ASSUMES twos complement integers // ASSUMES二进制补码整数

The explicit cast is because Rule 10.1 says 明确的强制转换是因为规则10.1

"The value of an expression of integer type shall not be implicitly converted to a different underlying type if ..." “如果...,则整数类型的表达式的值不得隐式转换为其他基础类型。”

Make it portable: 使其可移植:

S16 temperatureResult = -32767 - 1; S16 temperatureResult = -32767-1;

But anyway, if MISRA requires compatibility with ones complement computers (like some Cray supercomputers), then the guaranteed range of signed 16-bit is only [-32767 ... 32767] so you can't achieve what you're trying to do. 但是无论如何,如果MISRA需要与互补计算机(例如某些Cray超级计算机)兼容,则带符号16位的保证范围仅为[-32767 ... 32767],因此您将无法实现自己想要的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM