You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

Avoid performing bit manipulation and arithmetic operations on the same variable. Though such operations are valid and will compile, they can lead to lesser code readability. Specifically declaring a variable as containing a numeric value or a collection of bits makes the programmer's intentions clearer and can lead to better code maintainability.

Non-Compliant Coding Example 1

In this non-compliant example, both bit manipulation and arithmetic manipulation is performed on the integer type x. The end result is an optimized line of code that changes x to 5x + 1.

int x = 50;
x += (x << 2) + 1;

This is a legal manipulation that in two's-complement representation multiplies x by 5, then increments it by 1. Because the operation uses bit-shifting rather than multiplication, it performs faster on some processor types that do not have efficient integer multiplication datapaths.

Unfortunately, it is challenging to immediately understand the effect of the second line of code. The code is not self-documenting.

Compliant Solution 1

Changing the second line to reflect the arithmetic nature of x causes the programmer's intentions to become clearer.

int x = 50;
x = 5 * x + 1;

A reviewer might now know that the operation should be checked for integer overflow. This might not have been apparent in the original code listing.

Non-Compliant Coding Example 2

In this non-compliant example, the coder attempts to optimally divide x by 4.

int x = -50;
x >>= 2;

Though this code is likely to perform a division by 4, it is not guaranteed to. The system is free to use whatever representation of an integer it wishes. The result of this operation is dependent on whether the processor performs an arithmetic shift or a logical shift.

For example, if the internal representation of x is 0xFFFF FFCE (two's-complement), an arithmetic shift results in 0xFFFF FFF3 (-13 in two's-complement), while a logical shift results in 0x3FFF FFF3 (1 073 741 811 in two's-complement). The programmer may have not intended one of these results.

Compliant Solution 2

Change the shift to a division so that the intention is clear.

int x = -50;
x /= 4;

The compiler now knows exactly what the programmer intended, and it can select the correct assembly instruction.

Compliant Practice

In order to further separate bit collections and numeric types, it might be prudent to define a bit-containing type. A programmer can then run automated tools over the code in question to verify that only bit manipulations are performed on variables of this type.

typedef int bitcoll;
bitcoll x = 0x7f3;
x = (x << 2) | 3; /* shifts in two 1-bits from the right */

Risk Assessment

By complicating information regarding how a variable is used in code, it is difficult to determine which checks must be performed to ensure data validity. Explicitly stating how a variable is used determines which checks to perform.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

INTxx-A

2 (medium)

1 (unlikely)

2 (medium)

P4

L3

  • No labels