Note | ||
---|---|---|
| ||
This guideline has been deprecated by |
Integer types smaller than int
are promoted when an operation is performed on them. If all values of the original type can be represented as an int
, the value of the smaller type is converted to an int
; otherwise, it is converted to an unsigned int
(see INT02-C. Understand integer conversion rules). If the conversion is to a wider type, the original value is All char and short integer types are promoted to int or unsigned int before they are used in expressions. Consequently they receive high-order bits. These bits are either zero-extended for unsigned chars and shorts, values or are sign-extended for signed chars and shortstypes. Consequently, arithmetic bitwise operations performed on ints yield the same values as on chars and shorts (at least in the low-order bits). However, bitwise operations may yield surprising effectson integer types smaller than int
may have unexpected results.
Noncompliant Code Example
This noncompliant code example demonstrates how promotion to int
yields surprising effectsperforming bitwise operations on integer types smaller than int
may have unexpected results.
Code Block | ||||
---|---|---|---|---|
| ||||
uint8_t port = 0x5aU0x5a; uint8_t result_8 = ( ~port ) >> 4; |
In this example, a bitwise complement of port
is negated, first computed and then shifted 4 bits to the right. If both of these operations were are performed on a an 8-bit unsigned integer, then result_8
would will have the value 0x0aU
0x0a
. However, port
will is first be promoted to a 32-bit integer (signed or unsigned, depending on implementation) signed int
, with the following results (on a typical architecture where type int
is 32 bits wide):
Expression | Type | Value | Notes |
---|---|---|---|
|
|
0x0000005a
| |||
|
|
| |
|
|
| Whether or not value is negative is implementation-defined. |
|
|
|
Compliant Solution
In this compliant solution, we truncate the negation back down the bitwise complement of port
is converted back to 8 bits. Consequently, result_8
receives is assigned the expected value of 0x0aU
.
Code Block | ||||
---|---|---|---|---|
| ||||
uint8_t port = 0x5aU0x5a; uint8_t result_8 = (static_cast<uint8_t>uint8_t) (~port)) >> 4; |
Risk Assessment
Bitwise operations on shorts and chars can produce incorrect data.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP14-C | low | likely | high |
P3 |
L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Astrée |
| Supported |
...
Axivion Bauhaus Suite |
| CertC-EXP14 | Fully implemented | ||||||
CodeSonar |
| LANG.CAST.RIP | Risky integer promotion | ||||||
Compass/ROSE | |||||||||
| CC2.EXP14 | Fully implemented | |||||||
Parasoft C/C++test |
| CERT_C-EXP14-a | Avoid mixing arithmetic of different precisions in the same expression |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
Related Guidelines
...
...
...
...
References
Wiki Markup |
---|
\[[MISRA 04|AA. C References#MISRA 04]\] Rule 10.5 |
MISRA-C | Rule 10.5 |
...
EXP05-CPP. Do not use C-style casts 03. Expressions (EXP) EXP07-CPP. Do not diminish the benefits of constants by assuming their values in expressions