Deprecated
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 INT02C. Understand integer conversion rules). If the conversion is to a wider type, the original value is zeroextended for unsigned values or signextended for signed types. Consequently, bitwise operations on integer types smaller than int
may have unexpected results.
Noncompliant Code Example
This noncompliant code example demonstrates how performing bitwise operations on integer types smaller than int
may have unexpected results.
uint8_t port = 0x5a; uint8_t result_8 = ( ~port ) >> 4;
In this example, a bitwise complement of port
is first computed and then shifted 4 bits to the right. If both of these operations are performed on an 8bit unsigned integer, then result_8
will have the value 0x0a
. However, port
is first promoted to a signed int
, with the following results (on a typical architecture where type int
is 32 bits wide):
Expression  Type  Value  Notes 



 


 


 Whether or not value is negative is implementationdefined. 



Compliant Solution
In this compliant solution, the bitwise complement of port
is converted back to 8 bits. Consequently, result_8
is assigned the expected value of 0x0aU
.
uint8_t port = 0x5a; uint8_t result_8 = (uint8_t) (~port) >> 4;
Risk Assessment
Bitwise operations on shorts and chars can produce incorrect data.
Recommendation  Severity  Likelihood  Remediation Cost  Priority  Level 

EXP14C  low  likely  high  P3  L3 
Automated Detection
Tool  Version  Checker  Description 

Astrée  20.10  Supported  
Axivion Bauhaus Suite  6.9.0  CertCEXP14  Fully implemented 
CodeSonar  5.4p0  LANG.CAST.RIP  Risky integer promotion 
Compass/ROSE  
1.2  CC2.EXP14  Fully implemented  
Parasoft C/C++test  10.4.2  CERT_CEXP14a  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.
Related Guidelines
SEI CERT C++ Coding Standard  VOID EXP15CPP. Beware of integer promotion when performing bitwise operations on chars or shorts 
MISRAC  Rule 10.5 
7 Comments
Jesse Gough
Since this is a C guideline, the compliant example should be changed to:
Robert Seacord (Manager)
Thanks, I fixed this problem and also tried to make this a little more precise.
I'm giving some thought as to if this should be a separate guideline, or if it should be eliminated and the example integrated with INT02C. Understand integer conversion rules.
Robert Seacord (Manager)
This has now been cleaned up (a bunch). If this is going to remain an "informational" recommendation then I would combine it with INT02C.
If we keep it as a separate guideline it should be strengthened to "Do not perform bitwise operations on integer types smaller than int" and doing so should be diagnosed.
Of course, this is not right either because the compliant solution still violates this. At the end of the day, I think this guideline is just going to say "understand integer promotions/conversion rules" and consequently should be combined.
Martin Sebor
Since this is a subset of INT02C. Understand integer conversion rules merging the two makes sense to me.
Jesse Gough
I agree with combining them. I actually think the example given here was more of a gotcha due to the use of '~' in particular, and not really related to bitwise operations in general.
Robert Seacord
I've merged this guideline with INT02C. Understand integer conversion rules and marked it as deprecated.
Loic Etienne
gcc 4.8.4 warns about
1u << 63ul
(assuming 64bits long and 32bits int) and computes0
. Rightfully so? No promotion from1u
to1ul
.ISO/IEC 9899:201x, 6.3.1.8 (Usual arithmetic conversions): "Many operators that expect operands of arithmetic type cause conversions"; 6.5.7 (Bitwise shift operators): "The integer promotions are performed on each of the operands...". But I am not able conclude from that.