...
The first interpretation is that when this value is used as an rvalue (e.g., lvalue = rvalue), the type is "unsigned int
" as declared. An unsigned int
cannot be represented as an int
, so integer promotions require that this be an unsigned int
, and hence "unsigned".
...
Code Block |
---|
struct {
unsigned long long a:8;
} ull = {255};
|
<< The following examples need to be completed and tested >>
Non-Compliant Code Example 1
In the following non-compliant code example, cBlocks is multiplied by 16 and the result is stored in the unsigned long long int alloc
. The result of this multiplication can overflow because it is a 32 bit operation, and the resulting value stored in alloc
is invalid.
Code Block |
---|
struct { unsigned long long size: 24; } ull; void* AllocBlocks(ull cBlocks) { if (cBlocks == 0) return NULL; unsigned long long alloc = cBlocks.size * 16; return (alloc < UINT_MAX) ? malloc(cBlocks * 16) : NULL; } |
...
On architectures where unsigned long long int
is guaranteed to have 2x the number of bits as size_tupcast
the variable used in the multiplication to a 64-bit value. This ensures that the multiplication operation is performed.
Code Block |
---|
void* AllocBlocks(size_t cBlocks) {
if (cBlocks == 0) return NULL;
unsigned long long alloc =
(unsigned long long)cBlocks.size * 16;
return (alloc < UINT_MAX)
? malloc(cBlocks * 16)
: NULL;
}
|
The assumption concerning the relationship of unsigned long long int
and size_t
must be documented in the header for each file that depends on this assumption for correct execution.
References
- ISO/IEC 9899-1999 Section 6.7.2 Type specifiers
- MISRA 04 Rule 3.5