From kde-core-devel Thu Sep 11 01:43:53 2003 From: Michael Matz Date: Thu, 11 Sep 2003 01:43:53 +0000 To: kde-core-devel Subject: Re: macro for enum operations X-MARC-Message: https://marc.info/?l=kde-core-devel&m=106324473524547 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.