You've changed your question, which invalidates the previous answers.
The behavior of your program is not predictable in general.
The C standard only guarantees that int
can represent values in the range -32767
to +32767
(16 bits). On such a system, the constant 2147483648
is of type long
or long long
.
Even if int
is 32 bits, no padding bits, and two's-complement, 2147483648
is outside the range of int
, and may be of type long
or long long
.
This:
int i = 2147483648;
implicitly converts the long
or long long
value to int
. The result is implementation-defined -- or it can raise an implementation-defined signal.
On many systems, the implementation-defined result is going to be -2147483648
. IF it is, then this:
i = -i;
attempts to negate that value, yielding a result that's outside the range of int
. Unlike a conversion, an overflowing arithmetic operator such as unary -
has undefined behavior for signed types.
It's very likely that the program will behave as it does on your system, but no, it's not predictable as far as the C standard is concerned. The compiler is free to assume that your program's behavior is well defined, and generate code based on that assumption, so it's actually plausible that it could behave in some unexpected manner.
Also:
printf("%lu\n", sizeof(int));
This will work correctly if size_t
(the result of the sizeof
operator) is unsigned long
on your system. If it isn't, then again, you have undefined behavior. The correct format for size_t
is "%zu"
:
printf("%zu\n", sizeof(int));
That was introduced in C99, so some implementations (particularly Microsoft's) may not support it. You can also convert the argument to the appropriate type with a cast:
printf("%lu\n", (unsigned long)sizeof(int));
Whatever this code is trying to accomplish, there's almost certainly a clearer way to do it. If you want to be able to manipulate integers with values of 2147483648
, long long
or int64_t
is guaranteed to be big enough.