Re: [GD-General] The joy of type aliasing and C
Brought to you by:
vexxed72
From: Brian H. <ho...@py...> - 2003-12-26 20:00:53
|
> I think specifically the compiler according to the latest rules has > the right to really fool with your code, because according to the > rules the float and integer values cannot be related to each other > anyways, so why would the compiler care about ordering. That's my understanding as well. The confusion (and arguments) seem to stem from who believes the Final Authority is. Some argue that the standard is clear; others argue that compilers have more flexibility during optimization; etc. etc. > I also pointed this at the algorithms list, apparently the union > trick is something which is specifically ok with gcc, but I agree > it is not a good general solution. I think I read somewhere that if you access it the data through the union (i.e. not indirectly to a pointer to union member) that there will not be an aliasing problem, i.e.: union u { int x; float f; }; u a; a.f =3D 1.0f; y =3D a.x; The above should be fine (but again, the standard is not clear on this, at least that I could tell -- in fact, the phrase "type punning" only appears once in my copy of the draft C99 standard, and the substring "alias" only appears four times). That said, from 6.5.7: "An object shall have its stored value accessed only by an lvalue expression that has one of the following types: .. .. .. =97 an aggregate or union type that includes one of the aforementioned types [Ed: compatible types] among its members (including, recursively, a member of a subaggregate or contained union)" so: int y =3D u.x; Is obviously fine. But it's not clear how that relates if you've just stored to a.f. > I think there is a valid answer through the pointer manipulation > though. I have heard that (someday I must purchase the standard > instead of relying on hearsay) $18 from ansi.org. The C++ standard is $183. I think that sums up the differences between the two languages very succinctly =3D) > the new rules consider char * > special so that the compiler will not do any aliasing optimisation > around it. This has been around since the 1989 standard I believe, and I _think_ it has been extended void * as well. I _think_ that the following will obviate any aliasing concerns: int x =3D * ( int * ) ( ( void * ) &f ); Because a pointer of type "char *" or "void *" may have no assumptions made about aliasing. > So converting your float variable address to char pointer, and > constructing the integer through it should be the correct way. That is my belief as well. However I see people present the union trick more often, which concerns me. Brian |