C++: Compiler warning for large unsigned int
Solution 1
Integer literals in C are, by default, of type "signed int" (edit: but see comments for caveats). The last number there is too large to be represented as a signed 32-bit integer, and so you need to tell the compiler that it's an unsigned integer by suffixing it with "U", as:
2147483648U
Note that you can also add a suffix of "L" to make it a "long", but on many systems that's still 32-bit and thus irrelevant.
Also, there's a much less error-prone (and easier-to-read) way to write this code, with the bit-shift operator:
const unsigned int BITS[32] = {1U, 1U<<1, 1U<<2, 1U<<3, 1U<<4,
/* and so on */
1U<<31};
Or, writing in hexadecimal, if you don't like bit shifts for some reason:
const unsigned int BITS[32] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20,
/* and so on */
0x80000000U};
Solution 2
Your constant has to be specified as unsigned too, use
2147483648UL
(UL = Unsigned Long), or simply
2147483648U
for an unsigned int.
As your code is right now, a constant, which is by default a plain int
, and hence signed, is assigned to an unsigned int
, which generates your warning.
Solution 3
Not necessary to define data type as unsigned just type;
int variable_name=2147483648U;
else just convert decimal value to hex...
gruszczy
I lead and manage the Google Assistant on Speakers team.
Updated on June 03, 2022Comments
-
gruszczy about 2 years
I have following array, that I need to operate by hand on bitmaps.
const unsigned int BITS[32] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648};
Unfortunately, when compiled I get
warning: this decimal constant is unsigned only in ISO C90
How can I remove this?
-
gruszczy over 14 yearsWhy compiler treats it then as an int, rather then automatically turn it into uint? Especially, that it exactly knows in what type it will be stored.
-
Brooks Moses over 14 yearsPedandically speaking, the error isn't that from the fact the (plain int) constant is assigned to an unsigned int; the assignment is irrelevant. The error is because the value of "2147483648" is too large to be a signed int, and so there's an overflow in generating the signed int constant in the first place.
-
Brooks Moses over 14 yearsIn a lot of cases you can't know what type a constant is (for instance, as a function argument in a varargs function) so it has to be specified explicitly. It's confusing to have the type be implied some times and need to be specified explicitly in others, and also confusing to have the same constant be different types on systems with different int sizes. Also, because C never does type inference of that sort, adding it for this one case would complicate the parser quite a lot without significant benefit.
-
AnT stands with Russia over 14 years@gruszczy: In C89/90 an unsuffixed decimal constant must be interpreted as
int
,long
orunsigned long
(whichever fits first). In C99 it must be interpreted asint
,long
orlong long
(whichever fits first). This what the compiler is trying to say by this warning. Apparently, on this platformlong
has the same size asint
. The compiler is basically saying: "maybe you were trying to create asigned long
connstant or maybe even along long
constant, but by the C89/90 rules I have to make itunsigned long
. -
gruszczy over 14 yearsOK, thanks. And by the way: version with operators is indeed better. I didn't know, I could do that outside of a function, in an array initializer. Thanks a lot.
-
AnT stands with Russia over 14 yearsActually, the real reason for the warning is that the compiler has to choose
unsigned long
for the constant type. (Note, again, this constant is notunsigned int
, it isunsigned long
.) And it has to choose it in C89/90 specifically, instead of choosing a larger signed type (which it might support) or following C99 rules and choosinglong long
. This is what the warning is about and why it refers toISO C90
. In C99, for example, an unsuffixed decimal constant would never be given an unsigned type. -
AnT stands with Russia over 14 years@gruszczy: Just keep in mind that version with operators does not automatically protect you from overflow. This is something you have to watch for yourself, i.e. you'll have to specify the
u
orul
suffix anyway. -
Brooks Moses over 14 yearsAndreyT: Thanks for the clarification!
-
gruszczy over 14 yearsI'll try to remember about that. I am not used to those UL and L markers. I am programming in Python most of the time, so I need to get used to all that :-) Thanks for the advice.
-
Johannes Schaub - litb over 14 yearsIn fact, the situation is quite a bit complicated. It's not as easy as "it's always signed int": There are differences between all of C90, C99 and C++ and there are different treatment of hex/oct and decimal literals. It's all causing a big headache.