Hello, I'm getting many of this warning in my project which uses NXP header with enum definitions similat to this:
typedef enum _clock_attach_id { kFRO12M_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 0), kNONE_to_NONE = 0x80000000UL, } clock_attach_id_t;
The warning seems to be obvious because 0x80000000UL does not fit into int.
But the compiler manual v5.06 for µVision says about enum:
10.4 Structures, unions, enumeratons and bitfields in ARM C and C++
In C mode, and in C++ mode without --enum_is_int, if an enum contains only positive enumerator values, the storage type of the enum is the first unsigned type from the following list, according to the range of the enumerators in the enum. In other modes, and in cases where an enum contains any negative enumerator values, the storage type of the enum is the first of the following, according to the range of the enumerators in the enum: • unsigned char if not using --enum_is_int • signed char if not using --enum_is_int • unsigned short if not using --enum_is_int • signed short if not using --enum_is_int • signed int • unsigned int except C with --strict • signed long long except C with --strict • unsigned long long except C with --strict
Maybe I misinterpret this, but I would think the compiler should choose "unsigned int" in this case. If so, why is there the warning?
The code works as expected, but I would like to minimize the number of warnings in the project (without code modification). Disableing this warning is also not good because it might hide a "real" problem.
Regards, Gunnar
Change:
kNONE_to_NONE = 0x80000000UL,
to
kNONE_to_NONE = 0x80000000L,
I tried adding L and UL but it does not change anything. Compiler warning stays the same. If I move the mouse pointer in µVision editor the to the yellow triangle with '!' the editos shows "warning: enumerator value not representable in the underlying type 'int'"
If I replace 0x80000000 with -2147483648 the warning disappears, although the bit pattern is the same. (I didn't test the resulting code but I assume the code stays the same..)
I would prefer a different way, because with the next SDK update from NXP the problem is back again.
Maybe ( (int)0x80000000 )
The problem is that enum constant is different from enumerated type. The paragraph from the manual that you posted, talks about the type of an enumeration and not the enum constant.
AS per C99 standard, Section 6.7.2.2: 6.7.2.2 Enumeration specifiers Syntax 1 enum-specifier: enum identifieropt { enumerator-list } enum identifieropt { enumerator-list , } enum identifier enumerator-list: enumerator enumerator-list , enumerator enumerator: enumeration-constant enumeration-constant = constant-expression Constraints 2 The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
It clearly mentions that the enum constant should have a value representable as an int. On a 32 bit machine int, the value 0x80000000 doesn't fit into an int and hence the warning.
I am sorry but the behavior of your code is at the mercy of implementation and at best implementation defined.
From the Post of 20-Apr-2018 12:28 GMT, it seems that it may be NXP's code ... ?
"... with the next SDK update from NXP the problem is back again"
Yes, it is NXP's code.