macro for enum operations
Lubos Lunak
l.lunak at suse.cz
Thu Sep 11 12:41:27 BST 2003
On Thursday 11 of September 2003 03:43, Michael Matz wrote:
> Hi,
>
> On Wed, 10 Sep 2003, Ravikiran Rajagopal wrote:
> > In C++, enums have sizes that are not necessarily the same as those of
> > ints of any form.
>
> As written above this is not correct. The _size_ of an enum is the size
> of the underlying type, which is an integral type, not larger than int or
> unsigned int, if that type can represent all values of all enumerators
> (and if not any larger integral type, which on usual compilers is long
> long maximum).
>
> What you remember about the awkwardness of enum in C++ is, that the
> _values_ of an enum can be less than the values of the underlying type.
> For instance:
>
> enum {a,b,c};
>
> The enumerators have the values 0,1,2. The underlying type can be 'char'
> (hence sizeof == 1), or short, int, or any other integral type not larger
> than int. But the values for this enum only include 0,1,2,3, i.e. _not_
> the full range of the underlying type (which is the confusing difference
> to ISO C!).
This looks confusing (especially the 0,1,2 vs 0,1,2,3). Are you trying to say
that if I have
enum Values { V0 = 0, V1 = 1, V3 = 3 };
Values value;
value = static_cast< Value >( 2 ); // a)
value = static_cast< Value >( 4 ); // b)
that both a) and b) are incorrect?
>
> > If I understand the standard right (correct me if I am wrong), the size
> > can actually be larger than that of longs.
>
> Not really. If anything it could be long long at best, and that isn't
> part of ISO C++. Even if it would be, that would be the border. An enum
> can not be larger than any of the supported integral types.
>
> > So Simon's patch is not guaranteed to be safe in all corner cases.
>
> If he uses long it's only unsafe for enums which require long long, and
> those are seldom ;-)
The macros could of course use unsigned long long, if needed. We require long
long anyway if I'm not mistaken.
[snip]
> > I am particularly concerned about the "~" operator because the return
> > value needs to be converted to EnumType again and I wonder whether
> > truncation would cause problems with 1s complement vs 2s complement.
>
> ~ is indeed conceptually a problem. Not because of 1s vs 2s complement,
> but because of the backcast. Given this:
>
> enum E {a,b,c};
> long l = ~(long)a;
> enum E e = (enum E)l;
>
> the problem arises because l has the value -1L. This is outside the
> values of enum E, and hence the resulting enumeration value is
> unfortunately unspecified. It could be truncated, or anded, or the
> machine could explode. The problem of course is, that without the
> operator ~, the others make much less sense. For instance it's possible
> to set some bit by |, but it's impossible to remove it again (by & and ~).
> Choose your poison.
Would this be a problem even when using unsigned long instead of long?
Perhaps that could be fixed by passing bitmask of valid bits to the macro.
--
Lubos Lunak
KDE developer
---------------------------------------------------------------------
SuSE CR, s.r.o. e-mail: l.lunak at suse.cz , l.lunak at kde.org
Drahobejlova 27 tel: +420 2 9654 2373
190 00 Praha 9 fax: +420 2 9654 2374
Czech Republic http://www.suse.cz/
More information about the kde-core-devel
mailing list