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