Hello,
I have added U postfix to the integer but the problem still is the same.
I read following pages but didn't work. http://www.keil.com/support/docs/3243.htm http://www.keil.com/forum/14703/
#define M(x) (u32)(1U << (x%32)) enum{ eFirst = M(x) ..... eLast = M(31) // generate "integer operation result is out of range" }
Can I avoid this warning?
You should be able to cast it as an int to get rid of the warning.
(int)(1U << 31)
You'll want to make sure that it's actually doing what you want though.
You should be able to cast it as an int to get rid of the warning
Unfortunately the OP was considerate enough to reduce detail to a minimum and miss the selection of his toolset.
So, typecasting to int on C51 ain't gonna help none.
But would C51 support long enum values?
Wouldn't it be likely to complain already at M(15) (requires unsigned) or possibly M(16) (requires long)?
Try this expert bit of code
<code> #define M(x) (uint32_t)( ((uint32_t)1) << (x%32)) </code>
Lots of parentheses in your #define.
Now try M(35-32) and see if you are happy with your parentheses.
yes but I just try to fix the warning hes seeing. here it is with your problem fixed.
<code> #define M(x) (uint32_t)( ((uint32_t)1) << ((x)%32)) </code>
no charge this time.
Thanks for your replies,
I had tried the followings, Keil generates the warning.(Keil v5.16a)
typedef unsigned int u32; 1) #define M(x) (u32)( ((u32)1) << ((x)%32)) 2) #define M(x) (u32)( (1U) << ((x)%32)) 3) if I write also (u32)0x80000000 instead of M(31) in enum #define L(x) (u32)((1U) << ((x)%32)) #define T() ((u32)0x80000000) #define M(x) (u32)(((u32)1) << (x%32)) enum{ test_1=M(31), test_2=L(31), test_3=T(), }; compiling Gprs.c... ..\src\Gprs.c(14): warning: #66-D: enumeration value is out of "int" range test_1= (31), ..\src\Gprs.c(15): warning: #66-D: enumeration value is out of "int" range test_2= (31), ..\src\Gprs.c(16): warning: #66-D: enumeration value is out of "int" range test_3=
The implementation is free to choose the underlying type of an enum, but it must cover all values given.
Probably keil choose int and are letting you know your values are too big for what it wants.
You could consider defeat and use a series of defines.
I try to use unsigned 32bits in enum,
it is not possible?
In C, the type of an enumerator is int.
In C++, the type of an enumerator is its enumeration.
On a 32-bit platforma, that ultimately cannot work.
The key problem is not with the enum's underlying integer type, though. It's with the enum values. An enum constant, by definition of the programming language, is always of type (signed) int. So even though the enum's underlying type may be uint32_t, on a 32-bit platform no enum value can equal (1UL << 31), because that's bigger than INT_MAX. The actual value of that thing will instead be an undefined result; most likely INT_MIN, i.e. -(1<<31)
You're right, I had already changed, maybe It would be a good option of Signed/Unsigned enum while define it because I didn't get warning on some compilers.
1440 The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
Taken from:
c0x.coding-guidelines.com/6.7.2.2.html
Since int is signed, you cannot have a value greater that what can be put into an int. You are using a value beyond that limit, so you have a problem.
Thanks, you're right, enum must be portable and signed
If assuming a 32-bit machine with two-complement integers, the value
(int)(1u << 31)
would be possible to store in an enum for the C language.
But the actual value would be negative. So you would then need to continue to care about type casts to get your enumerated values to fold back into unsigned values again.
So it's better to let the enum just hold the bit positions (0..31) and in the actual code write (1u << bitname). The compiler will still see that both 1u and bitname are constants, allowing it to pre-compute the shifted value if the processor doesn't have a suitable instruction to do the shift on-the-fly.