This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Help with bit-field semantics in C and C++
Michael Matz <matz@suse.de> writes:
| Hi,
|
| On Fri, 27 Aug 2004, Gabriel Dos Reis wrote:
|
| > | So
| > |
| > | e = (E)7;
| > |
| > | printf ("%d\n", (int)e));
| > |
| > | should print 3, and not 7 as is does now, and this should work by
| > | converting integer types into enumeration types, and not by masking
| > | upon converting enumeration types to ints? Did I get that right?
| >
| > Yes, the masking happens when converting from integer to enumeration,
| > not from enumeration to integer.
|
| In this case I think the C++ standard should be changed in a way to not
| require a masking operation for each and every assignment from an integer
| of which the range is unknown. Yes this masking happens only for such
| casts, and not for every operation if the operands are enums already, but
| it still will hurt performance in the real world.
You assume that casting from an integer unknown value to enumeration is
a frequent operation (that sits at critical path).
| Additionally, the fact that every compiler in the world does _not_ do this
| masking and that standards should standardize existing practice strongly
| indicates that changing (I'm tempted to say correcting) the standard is
| the way to go.
There are many things existing C++ compilers (including GCC) get wrong.
| I believe such correction would require some deeper changes on what can be
| expected of an enum variable (in particular it wouldn't be ensured anymore
| that enum values really are in the range of the bitfield, but instead in
| the range of the underlying integer type, i.e. similar to C). I
| understand that we can't use real bitfields anymore to implement enums,
| but we don't loose anything by this, especially given that we don't do it
| right now (and I'm not even sure, if it would be allowed, that for
| instance an "enum {zero,one}" only has one bit storage, e.g. if combined
| with real bitfields in a struct).
Now, that change would introduce a unique integral-like type in the
language whereby when you see a variable of that type going by, you
can nolonger make good assertions about its value. Other C++ rules
(like incrementation, decrementation and usual arithmetic operations)
have been carefully outlawed based on the principle that when you get
an enumeration variable, you can safely assume that its value is in
range.
| The other type strictness rules can be retained, so from a type safety
| p.o.v. this doesn't need to change anything. But IMHO this requirement
| of having the value be masked most of the time is very suboptimal. I
| can't think of any reason why the writers of the standard would intend
| this behaviour, so I would assume an oversight when writing the standard
| itself.
Notice that the cast issue is just one of the cases where the standard
text is consistent in that regard: ++e, --e, e += 2, etc. are just
forbidden as well. This is an area where those decisions have been
conciously taken.
-- Gaby