Richard Heathfield said:
Pietro Cerutti said:
If you meant those to be bit counts rather than byte counts, your code
invokes undefined behaviour.
Let me expand on this. Consider the first assignment:
sclen_hi = scnlen >> 32;
scnlen has type "unsigned long long", which is at least 64 bits
wide. Thus, shifting it right by a mere 32 bits is
well-defined. The result is then assigned to sclen_hi, which has
type "unsigned int". Regardless of whether "unsigned int" is
large enough to hold 32 bits, the assignment is acceptable: any
high bits will simply be trimmed off.
Consider the second assignment:
sclen_lo = scnlen & 0xFFFFFFFF;
I believe that 0xFFFFFFFF has type "int", "unsigned int",
"unsigned long int", or "unsigned long long int", depending.
Regardless of its type, the "&" operation against scnlen will
cause it to be promoted to "unsigned long long int". The result
is assigned to sclen_lo.
The possibility for undefined behavior seems to be in the range
of "int", which is the type of sclen_lo. If "int" is 32 bits,
then converting a large 32-bit unsigned integer to "int" invokes
undefined behavior, because it is outside the range of "int". I
imagine that this is what Richard is talking about.
Another possibility is that Richard is concerned about the
possibility of padding bits in various types. Padding bits are
interesting theoretically but rarely come up in real life, so I'm
not going to go any further in this direction.
The example number of 888888 would not yield undefined behavior,
as far as I can see. I don't think that's the issue at hand.