Take, for instance, 0xffffffffL
.
Suppose int is 32 bits, is 0xffffffffL
the same as (long)0xffffffff
? In other words, is the type of 0xffffffffL
long?
Since the type of 0xffffffff
is unsigned int
, I think that 0xffffffffL
is unsigned long
rather than signed long
, though I'm not sure.
Does that depend on whether long
is 32 or 64 bits?
Quoting from C99 draft standard N1256 (emphasis mine):
6.4.4.1 Integer constants
[...]
Description
An integer constant begins with a digit, but has no period or exponent part. It may have a prefix that specifies its base and a suffix that specifies its type.
[...]
Semantics
The type of an integer constant is the first of the corresponding list in which its value can be represented.
[...]
Suffix Decimal Constant Octal or Hexadecimal constant -------------------------------------------------------------------------- none int int long int unsigned int long long int long int unsigned long int long long int unsigned long long int -------------------------------------------------------------------------- [...] -------------------------------------------------------------------------- l or L long int long int long long int unsigned long int long long int unsigned long long int
[...]
If an integer constant cannot be represented by any type in its list, it may have an extended integer type, if the extended integer type can represent its value. If all of the types in the list for the constant are signed, the extended integer type shall be signed. If all of the types in the list for the constant are unsigned, the extended integer type shall be unsigned. If the list contains both signed and unsigned types, the extended integer type may be signed or unsigned. If an integer constant cannot be represented by any type in its list and has no extended integer type, then the integer constant has no type.
Thus, according to the above citation:
Neither the type or the size of a constant such as 0xffffffffL
is uniquely identified by the suffix. It depends also on the actual bit width of a long
, which is implementation defined (with a minimum of 32 bit).
0xffffffff
is not guaranteed to be unsigned int
. unsigned int
has a minimum guaranteed bit width of 16, thus if you are on a platforms where int
s are 16 bit, 0xffffffff
could well be unsigned long
. 0xffffffff
can also be an int
(as pointed out in a comment), i.e. it is not even guaranteed to be unsigned, if int
type can be used to represent it (e.g. platforms where int
is 64 bit).
Adding a parenthesized type in front of an expression is a type casting operation, which forces the conversion of the constant to the type indicated in parentheses. Thus the result of the cast (long)0xffffffff
will have type long
, but the value depends on a variety of factors, as stated by the standard:
6.3 Conversions
[...]
6.3.1.3 Signed and unsigned integers
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With