...
In this compliant solution, the integer constant -1 is used to set all bits in mask to one. The integer constant -1 is of type signed int. Because -1 cannot be represented by a variable of type unsigned long, it is converted to a representable number according to the rule in Section section 6.3.1.3, paragraph 2, of the C Standard [ISO/IEC 9899:2011]:
...
"One more than the maximum value that can be represented in the new type," ULONG_MAX + 1, is added to -1, resulting in a right-side value of ULONG_MAX. The representation of ULONG_MAX is guaranteed to have all bits set to one by Section section 6.2.6.2, paragraph 1:
For unsigned integer types other than
unsigned char, the bits of the object representation shall be divided into two groups: value bits and padding bits (there need not be any of the latter). If there are N valuebits, each bit shall represent a different power of 2 between 1 and 2N − 1, so that objects of that type shall be capable of representing values from 0 to 2N − 1 using a pure binary representation; this shall be known as the value representation. The values of any padding bits are unspecified.
...
In this noncompliant code example, a programmer attempts to set the most significant bit.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
const unsigned long mask = 0x80000000; unsigned long x; /* Initialize x */ x = (x ^ mask) + 1; |
...
A portable (and safer) way of setting the high-order bit is to use a shift expression, as in this compliant solution.:
| Code Block | ||||
|---|---|---|---|---|
| ||||
const unsigned long mask = (1 << ((sizeof(unsigned long) * CHAR_BIT) - 1)) unsigned long x; /* Initialize x */ x = (x ^ mask) + 1; |
...
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| CERT C++ Secure Coding Standard | INT17-CPP. Define integer constants in an implementation-independent manner |
Bibliography
| [Dewhurst 2002] | Gotcha #25, "#define Literals" |
| [ISO/IEC 9899:2011] | Section 6.2.6, "Representations of Types" Section 6.3.1.3, "Signed and Unsigned Integers" |
...