RE: [GD-General] The joy of type aliasing and C
Brought to you by:
vexxed72
From: Brian H. <ho...@py...> - 2003-12-28 18:02:43
|
> a pretty fruitless exercise. If you really want binary > compatibility, then you have to accept that the basic types will > have to be the same on all platforms, and that's something they are > not prepared to accept, as it will hurt performance on non- > conforming systems. Spot on. And I don't mind that a lot of operations are undefined or implementation defined, but what bothers me is the head-in-the-sand "we don't talk about these things" attitude. It is pretty much impossible to write a portable C program that does anything useful. > If the standards committee wanted to be actually helpful, they > would have specified exceptions to these rules, such as: when the > two types have identical size and alignment, type punning is well- > defined. Actually, if they had simply made it "implementation defined" with some caveats, that would have helped, because in practice this is all implementation defined and not truly "undefined". "Undefined" has connotations of causing your computer to explode. > The real insult is that idioms like *(int *)&f are commonly used, > and generally handled as expected (by users not the standard) by > most compilers. SHHHHHHHHHHHH! > This is a case where the real standard is the > standard which actually exists in practice and not the standard > that some academics have made up. Well, I wouldn't go that far, because in reality there are too many areas where what works in practice WILL explode on other systems. The x86 has made this an unfortunate problem. A common example is: struct foo { char b; /* assume tight packing */ int x; }; char buffer[ 1024 ]; struct foo *f =3D ( struct foo * ) buffer; int y; fread( fp, buffer, 1, sizeof( buffer ) ); y =3D f->x; /* misaligned access, fine on x86, crashes on, say, SPARC */ So I understand their rather dogmatic desire to make sure everyone follow the rules, but I don't like the attitude that "writing real software is unclean, even if you know what rules you're breaking". But I digress...the one thing I can definitely say I've taken away from this is that when someone yells at me for type-alias violation, I'll just turn around and say that code is undefined and therefore THEY'RE WRONG TOO, HAH! =3D) Anyway, near as I can tell, if you want the int bits, and you can ASSUME that sizeof( float ) =3D=3D sizeof( int ) and you can ASSUME a certain endianess, then the following should work no matter what: float f =3D 1.0f; int i =3D 0; unsigned char *c =3D ( unsigned char * ) &f; if ( sizeof( f ) ! =3D sizeof( i ) ) explode(); /* do some endianess verification as well */ .. .. .. i =3D ( c[ 0 ] << 24 ) | ( c[ 1 ] << 16 ) | ( c[ 2 ] << 8 ) | ( c[ 3 ] ); Brian |