I have the following code.
uint32_t reg_val = 0;
uint64_t val = 0;
reg_val = 0;
reg_val = ((val & 0xffffff000000) >> 24);
dev_write(rw,reg_val);
The compiler gives a warning that says
warning: integer constant is too large for "long" type
I am only assigning 24 bits to reg_val which is define to be unsigned integer of size 32bits.
Why is the compiler generating this warning?
The constant 0xffffff000000
is too large for a 32-bit long, which ranges to 0x7fffffff
in your case.
Write it as 0xFFFFFF000000ULL
( unsigned long long
) or avoid the issue by writing
reg_val = (val >> 24) & 0xFFFFFF;
Expanding on greggo's fine answer a bit.
How an integer literal is defined depends on which version of language we are in.
In C99, integer literals automatically have a type which can contain their value (unless no such type exists). So, assuming 32-bit long
, then this constant would already have type unsigned long long
, so no warning should occur.
I don't have a copy of the C89 text, but C89 does not have long long
. If the rules are similar, then what would happen would be that the constant is converted to 32-bit unsigned long
in an implementation-defined manner (probably, truncating higher bits).
Since the OP got a warning, but is also able to solve it with the ull
suffix, it suggests that he is using compiler extensions. In theory, if a compiler offers long long
in a C89-like mode, then it should also update its integer literal rules, so that a literal that cannot fit in long
has type long long
(possibly unsigned).
However, I have heard that compilers exist that don't do this; they truncate the literal instead of giving it a type that fits, unless you put the suffix on yourself.
tl;dr - suffix shouldn't be necessary; but it never hurts to use it, and it can work around badly-implemented compiler extensions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.