cast truncates bits from constant value (8000000000000000 becomes 0)

Linus Torvalds torvalds at osdl.org
Sat Dec 2 08:19:27 EST 2006



On Fri, 1 Dec 2006, Al Viro wrote:
> 
> "C++ way of doing things" is hardly an endorsement.  _IF_ we are changing
> the way enum works, might as well do it sanely and have the type of
> enumeration constant same as that of expression initializing it (with
> usual implicit initializers).  But yes, that explicitly changes semantics -
> enum { A = 0L, B, C }; will have A, B and C long, not int.  Direct
> contradiction with C90/C99...

Well, the C++ definition at least means that enumerated names have the 
same types _after_ the enumaration is closed (ie the example I sent out 
will at least give the same value for the sizeof() of everything).

So the C++ definition is a lot saner than what gcc does now.

On the other hand, I do agree that "keeping the enumerated type the same 
as the initializer expression type" is _also_ a sane situation. And it's 
better than the C++ situation in the sense that at least the sizes are 
_consistent_ (which C++ is not - the size AT DEFINITION time is 
potentially different from the size AFTER the definition).

So in the C++ world, you have the odd situation that

	enum strange {
		one = (char) 1,
		other = sizeof(one),
	};

we will actually end up with

	other != sizeof(one)

AFTER the declaration (because when "other" got its value, "one" had a 
type of "char", but _after_ the declaration, "one" will have a type of 
"size_t" or "int" or whatever, because the final type of "one" depends on 
the type of the enumerator.

So the C++ definition is really odd, but it's better than what gcc does, 
because at least all the values end up having a common type at the end.

The version where all the values _keep_ their types all the time, and you 
can force them to be whatever you want (by just making sure the 
initializer expression has the right type) is the most flexible one and at 
least doesn't have inconsistencies like the above example, but it's 
neither what gcc nor the C++ standard (or any older C standard, for that 
matter) actually says.

Anyway, because of all this, enum types are a mess. sparse warns if you 
can't fit it in an "int", which is the traditional and fairly dependable 
old C behaviour, and basically says "extended integer types for enums are 
flaky as hell - warn about them!"

		Linus



More information about the Linuxppc-dev mailing list