macro for enum operations

Michael Matz matz at kde.org
Thu Sep 11 02:43:53 BST 2003


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!).

> 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 ;-)

> Please see Dirk's recent commits regarding implicit conversion of enums
> to ints and the problems with gcc 3.4.

These all have to do with the problem, that in a variable of type 'enum X'
where X was defined in Qt to contain enumerators in a certain range, some
values outside of that range were stored by KDE code (in a sense those
enums were tried to be extended in KDE).  This is what doesn't work (and I
consider this a bug in the standard).

> 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.


Ciao,
Michael.





More information about the kde-core-devel mailing list