4 ms·
In C, 0x81000000 is always a signed number, since that's a regular "int"-type literal (like "17"). Whether it's negative or not is of course implementation-depe
by unwind 10y ago
In C, 0x81000000 is always a signed number, since that's a regular "int"-type literal (like "17"). Whether it's negative or not is of course implementation-dependent, on a 32-bit system with 32-bit "int" it will be since bit 31 is set.
To make it unsigned you'd have to append an 'u'.
I'm sure you know this, but people somehow sometimes seem to magically expect "certain" literals to be unsigned just because they're hex, and that's not how it works.'
EDIT: It seems I forgot about the complexities pointed out by replies to this comment. Thanks. Now the only think I'm certain about is that I'm confused.
- userbinator 10y agobut people somehow sometimes seem to magically expect "certain" literals to be unsigned just because they're hex, and that's not how it works Indeed, and in the most general sense, the signed/unsigned is really nothing more than how those 32 bits are interpreted by whatever operates on them. C attaches a particular type to literals which is used by the built-in operators, but things like printf() to a certain extent will do their own interpretation, as this shows: printf("%d %u %x", 0x81000000, 0x81000000, 0x81000000); This is definitely a concept that seems quite unfamiliar to those used to higher-level languages.
- cremno 10y agoThat's not true. Hexadecimals integer constants without suffix may have a signed type but they also may have an unsigned one. For example, 0x81000000 usually has type unsigned int. http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5 http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5
- ryao 10y agoPassing %d to printf says to print an int. 0x81000000 is a negative number when processed as a 32-bit signed integer. The output is the two's complement interpretation of the value. To print an unsigned int, you should pass %u. This would be more obviously correct if %x were used to print the hexadecimal representation, which is 0x81000000.
- pascal_cuoq 10y agoJust a small remark, on any platform that has 32-bit integer types and 64-bit integer types and nothing in between, regardless of how these are mapped to int/long/long long, 0x81000000 is an unsigned integer. You can see the C11 rules here and work through them for yourself: http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5 http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5 The rules were identical in C99 and different in C90. This is not very important for the discussion though. What is important for the discussion, and is perhaps left too implicit—but there is a maximum useful length for a blog post and this one is already close—is: - Any C variant (C90 or C99/C11) will try hard to pick a type for the literal 0x81000000 in which the desired value is representable. C99/C11 will always succeed, because they specify long long which has to allow to represent this value. A C90 compiler will also succeed because it guarantees a 32-bit unsigned long type which has to allow to represent this value. - in ptr + offset, the particular integer type of “offset” does not matter. This expression is defined exactly the same regardless of whether offset is a signed char or an unsigned long long. The type of offset can be an integer type way wider than size_t/ptrdiff_t, and the expression still works as long as the result is in-bounds for the array that ptr is pointing to.