(assuming 64bit machine)
int n = 0xFFFFFFFF; //max 32bit unsigned number printf("%u\n", n);
The maximum positive number that a regular signed integer (32bit) can store is
In the above example I'm assigning the maximum unsigned integer value to a regular signed integer, I'm receiving no warnings or error from GCC, and the result is printed without problems (with
L to the hex constant changes nothing.
Why is that?
0xFFFFFFFF, on a platform where
unsigned has a maximum value of 232-1, will have the type
unsigned according to "184.108.40.206 Integer Constants" of the Standard.
And then we get to the conversion:
220.127.116.11 Signed and unsigned integers
1 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, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.60)
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-deﬁned or an implementation-deﬁned signal is raised.
So, the result is implementation-defined or raises an implementation-defined signal.
Now, you print your
int with the format
%u, which is just plain mismatched. And while that is strictly speaking UB, you will likely get the original constant, assuming you have 2s-complement and the original assignment used wrap-around.
The C standard doesn't specify the behaviour but requires that the implementation specifies it. GCC always uses 2's complement representation and converts via truncation, therefore
int32_t i = 0xFFFFFFFF; will result in
i being set to -1 when compiled with GCC. On other compilers YMMV.
To get the warning from GCC you need to give the
% gcc 0xfffffff.c -c -Wsign-conversion 0xfffffff.c:1:9: warning: conversion of unsigned constant value to negative integer [-Wsign-conversion] int i = 0xFFFFFFFF; ^~t ~~~~~~~~
In general C compilers by default produce warnings only about very blatant errors and of constraint violations. The
-Wsign-conversion would make many compilations very noisy - even those that are well-defined, like:
unsigned char c = '\x80';
unsignedchar.c:1:19: warning: negative integer implicitly converted to unsigned type [-Wsign-conversion] unsigned char c = '\x80'; ^~~~~~
on implementations where
char is signed.
unsigned int are 32 bits, which is the case on most platforms you're likely to be using (both 32-bit and 64-bit systems). Then the constant
0xFFFFFFFF is of type
unsigned int, and has the value 4294967295.
int n = 0xFFFFFFFF;
implicitly converts that value from
unsigned int to
int. The result of the conversion is implementation-defined; there is no undefined behavior. (In principle, it can also cause an implementation-defined signal to be raised, but I know of no implementations that do that).
Most likely the value stored in
n will be
Here you use a
%u format specifier, which requires an argument of type
unsigned int, but you pass it an argument of type
int. The standard says that values of corresponding signed and unsigned type are interchangeable as function arguments, but only for values that are within the range of both types, which is not the case here.
This call does not perform a conversion from
unsigned int. Rather, an
int value is passed to
printf, which assumes that the value it received is of type
unsigned int. The behavior is undefined. (Again, this would be a reasonable thing to warn about.)
The most likely result is that the
int value of
-1, which (assuming 2's-complement) has the same representation as
0xFFFFFFFF, will be treated as if it were an
unsigned int value of
0xFFFFFFFF, which is printed in decimal as
You can get a warning on
int n = 0xFFFFFFFF; by using the
-Wsign-conversion option. These option are not included in
-Wall. (You'd have to ask the gcc maintainers why.)
I don't know of an option that will cause a warning on the
(Of course the fix is to define
n as an
unsigned int, which makes everything correct and consistent.)
User contributions licensed under CC BY-SA 3.0