I am using PCLint v 9.00h
In my code I have the following (where S16 is a signed 16 bit):
S16 temperatureResult = -32768;
Which unless
The standard only guarantees the range of [-32767,32767] for signed short. Your implementation may extend this a bit, like most implementations do, but PCLint checks for standards compliance.
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. PCLint simply didn't bother to check whether the actual value fits into the destination type.
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. In C language -32768
is not an atomic constant. -32768
is actually an expression consisting of an unary -
operator applied to a positive constant 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
. Consequently, -32768
is evaluated in the domain of a larger type and also ends up as a value of larger type. PCLind decided to warn you about the implicit switch to a larger type. (See (-2147483648> 0) returns true in C++? for more details.)
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.
First of all: it doesn't have to deal with -32768 by standard:
5.2.4.2.1 Sizes of integer types
[...]
— minimum value for an object of type short int
SHRT_MIN -32767 // -(215 - 1)
— maximum value for an object of type short int
SHRT_MAX +32767 // 215 - 1
(I'm looking for the part which makes a enviroment defined note about supporting -32768 anyway)
Got it:
The reason why there is sometimes anyway one more number supported is justified by this paragraph:
6.2.6.2 Integer types
[...]
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. 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). 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:
— the corresponding value with sign bit 0 is negated (sign and magnitude);
— the sign bit has the value -(2N) (two’s complement);
— the sign bit has the value -(2N - 1) (ones’ complement).
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. In the case of sign and magnitude and ones’ complement, if this representation is a normal value it is called a negative zero.
(All I'm quoting is written in ISO/IEC 9899:TC3)
It comes to mind to try:
S16 temperatureResult = (S16) 0x8000; // ASSUMES twos complement integers
The explicit cast is because Rule 10.1 says
"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;
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.