I am reading Jans Gustedt's "Modern C". In a discussion about how the types for numerical literals are determined, he writes about the common pitfall of assigning 0xFFFFFFFF
to a signed
variable:
A common error is to try to assign a hexadecimal constant to a signed with the expectation that it will represent a negative value. Consider a declaration such as int x = 0xFFFFFFFF. This is done under the assumption that the hexadecimal value has the same binary representation as the signed value −1. On most architectures with 32-bit signed, this will be true (but not on all of them); but then nothing guarantees that the effective value +4294967295 is converted to the value −1.
I want to clarify the meaning of the bolded statement. Does the statement merely state that
Or, is it trying to make the point that
If the latter, why would this be? Wouldn't the fact that the hexadecimal value has the same bit representation as -1 on architectures with 32-bit signed guarantee that the conversion will succeed there?
is it trying to make the point that
- Even on architectures with 32-bit signed, nothing guarantees that the effective value +4294967295 is converted to -1?
^ This.
If the type of 0xffffffff
is unsigned, as stipulated, then assignment to an object of type [signed
] int
induces a conversion to that type. The language spec says:
When a value with integer type is converted to another integer type other than
bool
, if the value can be represented by the new type, [...]. Otherwise, if the new type is unsigned, [...] Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
(C23 6.3.1.3)
The spec allows for a signal to be raised instead of the conversion proceeding, and if no signal is raised then then the result of the conversion is up to the implementation. The common error Gustedt describes amounts to assuming that the bit pattern of the unsigned value will be reinterpreted as a that of a signed int
. Some implementations in fact do that, but they are not required to do, and there are other plausible alternatives. For instance, out of range values might be converted to an extreme value of the destination type.