enum size question

The following code compiles with gcc but not the Sun compiler:

#include <limits.h>

enum a{ aA = ~(1<<10)} ;

enum b{ bA = ULONG_MAX} ;

enum c{ cA = ~(1<<10), cB = ULONG_MAX} ;

> CC -c -m32 test.cpp

"test.cpp", line 4: Error: c is not within the range of a long or unsigned long.

From a quick browse, it appears gcc enums are of type unsigned but Sun enums are signed. But if that is the case the above is rather confusing:

- firstly the error message does not indicate which member of c is causing the problem

- the error is ambiguous. What is the limit, is it long or unsigned long? If the latter I believe it should be ok. The fact the error says "[b]or[/b] unsigned long" means that must be an option - if so, can I enable enums to be of type unsigned somehow?

- Why does it give me an error for enum c but not a or b, which contain the same values?

Our code is full of enums using ~x and using unsigned UINT_MAX values, so this looks like it could be a showstopper for us in our Sun compiler evaluation. Any information is appreciated.

[1394 byte] By [martinwatt] at [2007-11-26 9:01:03]
# 1

Sun C++ follows the C++ standard (refer to section 7.2).

An enumeration type has an underlying type that is large enough to hold all the enumeration values. The type shall not be larger than int unless the value won't fit in an int or unsigned int. Other possible underlying types include long and unsigned long.

In this case, the enumeration values are -1025 and ULONG_MAX. That range of values cannnot be represented in a 32-bit environment by type long (can't represent ULONG_MAX) or unsigned long (can't represent a negative value). The error message does not point to either value because either one is OK by itself -- the combination is not OK.

Experimenting with g++ shows that it uses type long long for the underlying type, a non-standard language extension. Sun C++ does not support enums larger than long or unsigned long.

To make your code conform to the requirements of the C++ Standard, you must restrict the range of the enum values. Depending on whether you intend ~(1<<10) to be treated as negative or as unsigned, two choices are enum c { cA = unsigned(~(1<<10)) , cB = ULONG_MAX } ;

enum c { cA = ~(1<<10) ,cB = LONG_MAX } ;

clamage45 at 2007-7-6 23:06:45 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 2
Excellent. Thanks for the clear and concise answer. That gives me exactly what I need to resolve my problem.
martinwatt at 2007-7-6 23:06:45 > top of Java-index,Development Tools,Solaris and Linux Development Tools...