gamedevlists-general Mailing List for gamedev (Page 28)
Brought to you by:
vexxed72
You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
(28) |
Nov
(13) |
Dec
(168) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(51) |
Feb
(16) |
Mar
(29) |
Apr
(3) |
May
(24) |
Jun
(25) |
Jul
(43) |
Aug
(18) |
Sep
(41) |
Oct
(16) |
Nov
(37) |
Dec
(208) |
| 2003 |
Jan
(82) |
Feb
(89) |
Mar
(54) |
Apr
(75) |
May
(78) |
Jun
(141) |
Jul
(47) |
Aug
(7) |
Sep
(3) |
Oct
(16) |
Nov
(50) |
Dec
(213) |
| 2004 |
Jan
(76) |
Feb
(76) |
Mar
(23) |
Apr
(30) |
May
(14) |
Jun
(37) |
Jul
(64) |
Aug
(29) |
Sep
(25) |
Oct
(26) |
Nov
(1) |
Dec
(10) |
| 2005 |
Jan
(9) |
Feb
(3) |
Mar
|
Apr
|
May
(11) |
Jun
|
Jul
(39) |
Aug
(1) |
Sep
(1) |
Oct
(4) |
Nov
|
Dec
|
| 2006 |
Jan
(24) |
Feb
(18) |
Mar
(9) |
Apr
|
May
|
Jun
|
Jul
(14) |
Aug
(29) |
Sep
(2) |
Oct
(5) |
Nov
(4) |
Dec
|
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(11) |
Sep
(9) |
Oct
(5) |
Nov
(4) |
Dec
|
| 2008 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(34) |
Jun
|
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(4) |
| 2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Alen L. <ale...@cr...> - 2003-12-30 07:04:47
|
>There is no portable way to recompress to a float16, since float16 is >not portable. Surely, most hardware cannot work with float16 natively, but it is still useable for lossy compression of some data. As long as I define what I want my float16 to look like, it is not less portable than any other user defined type. Generally, trying to look at a float as if it's some kind of a black box that stores real numbers, is kinda silly. You have to be aware of its internal representation, or you can't work with it (without getting yourself into various precision losses, etc). And once you are aware, you should be able to access it. But I believe we all agree on that, and it's the standard that has a wrong approach here. Alen |
|
From: Brian H. <ho...@py...> - 2003-12-29 19:32:50
|
On Mon, 29 Dec 2003 11:20:31 -0800, Tom Hubina wrote: > At 02:57 AM 12/29/2003, you wrote: >> I don't know about C99, but the C++ standard simply states that >> the compiler is allowed to assume that there no aliasing between >> pointers of two different types. >> > > Do you have a specific reference to this? Both standards state this, kind of. In C99, it's section 6.5, paragraph 7, where it specifically says "An object shall have its stored value accessed only by an lvalue expression that has one of the following types:" At which point it lists all the types that are compatible with that retrieval. There's a footnote that specifically mentions "The intent of this is to specify those circumstances in which an object may or may not be aliased". Since integers and floats are not considered compatible types, that indicates that the compiler can assume that they cannot be aliased. In the C++ 98 standard, 3.10 paragraph 15, there's the statement "If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behaviour is undefined:" and it lists a very similar group to the C standard, and has a verbatim footnote of the intention footnote. The list a little bit longer simply because C++ has more type rules (e.g. base class accessed through child class pointer is legal), but is otherwise identical. Brian |
|
From: Tom H. <to...@ve...> - 2003-12-29 19:21:25
|
At 02:57 AM 12/29/2003, you wrote: > I don't know about C99, but the C++ standard simply states that the >compiler is allowed to assume that there no aliasing between pointers of two >different types. Do you have a specific reference to this? Tom |
|
From: Brian H. <ho...@py...> - 2003-12-29 16:45:25
|
> int _fpclass(double); Not portable. The C99 standard introduced classification as a standard macro: int fpclassify(double x); Which returns one of the predefined classification macros (FP_INFINITE, etc.). These are expected to be in <math.h> I'm hoping/assuming that even "lightly compliant" C99 compilers will have these in them. It also specifies isfinite(), isnan(), etc. There is no portable way to recompress to a float16, since float16 is not portable. Brian |
|
From: Alen L. <ale...@cr...> - 2003-12-29 11:30:58
|
> Yep:
> int _fpclass(double);
Yes of course. But, the purist argument was "this is not portable". Heck, I
think checking out the bits of *(int*)&f is much more portable than
_fpclass(). ;)
> BTW I tend to write this:
>
> int x = ( int & ) f;
>
> instead of:
>
> int x = * ( int * ) &f;
>
> Any known difference ?
AFAIK, references are just syntactic sugar, so I see no reason why there
should be a semantic difference. But then again, recasting across a char*
before casting to int* shouldn't make a difference either (logically), but
according to the standard it does. :/
Anyway, using something like:
inline int &FloatAsInt(float &f) { return (int&)f; }
should allow you to fix it by putting a lot of #ifs in there if you have
problems with particular compiler(s) later.
--
Alen
|
|
From: Stefan B. <ste...@di...> - 2003-12-29 10:57:41
|
I don't know about C99, but the C++ standard simply states that the
compiler is allowed to assume that there no aliasing between pointers of two
different types. This means that in the following snippet, the value of 'i'
may be different depending on how aggressive the compiler is when
optimising:
float f = 0.0f;
int* ip = (int*) f;
*ip = 2345;
f = 4532.3f;
int i = *ip;
This is a real issue that could cause very strange bugs on various
platforms (PS2 is the most common target where this can pop up).
However, as I said I am unsure about C. I don't think it has this rule as
it's been touted as one reason why C++ code can actually be quicker than C
code. C99 introduces restricted pointers which allow the same thing but I
believe you have to hint the compiler explicitly rather than relying on a
semi-obscure language rule.
/Stef!
--
Stefan Boberg
CTO @ Digital Illusions CE
-----Original Message-----
From: Brian Hook [mailto:ho...@py...]
Sent: den 26 december 2003 19:04
To: gam...@li...
Subject: [GD-General] The joy of type aliasing and C
About a year and a half ago there was a fairly major brouhaha on the
algorithms list about this line of code:
int x = * ( int * ) &somefloat;
Now, let's push aside endianess and size issues, the concern was that
since there was "type-aliasing" that Something Bad could happen.
Something Bad, of course, being a rather ambiguous statement.
I'm aware of all the bad things that can happen if you have
type-aliasing in conjunction with pointer aliasing, which is related,
but that one line above doesn't seem like it should be bad _with a
legal C compiler_.
The major concern are optimizations that the compiler may make that
affect order. For example:
somefloat = 1.0f;
x = * ( int * ) &somefloat;
In theory, a heavily optimizing C compiler would see that the
assignment to somefloat should not affect the assignment to x since
they are incompatible types, which may allow it to decide to assign to
somefloat _after_ the assignment to x.
But that would be illegal. The C specification states that the end of
every expression is a sequence point, and thus the assignment to
somefloat MUST be flushed before any subsequent statements are
executed.
So, I can buy that the aliasing thing is a serious concern if there is
concern about a C compiler aggressively optimizing and doing it
incorrectly, but that doesn't seem to be the argument.
Of course, granted, using a union makes more sense and is a bit
cleaner, I'm fine with that:
union
{
int i;
float somefloat;
} u;
u.somefloat = 1.0f;
x = u.i;
But according to the C standard, the above is undefined ("If the value
being stored in an object is accessed from another object that
overlaps in any way the storage of the first object, then the overlap
shall be exact and the two objects shall have qualified or unqualified
versions of a compatible type; otherwise, the behavior is
undefined.").
Anyone have something more authoritative on this issue?
Brian
-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills. Sign up for IBM's
Free Linux Tutorials. Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id78&alloc_id371&op=click
_______________________________________________
Gamedevlists-general mailing list
Gam...@li...
https://lists.sourceforge.net/lists/listinfo/gamedevlists-general
Archives:
http://sourceforge.net/mailarchive/forum.php?forum_idU7
|
|
From: Pierre T. <pie...@no...> - 2003-12-29 08:39:34
|
> No need to mention performance at all. Does anyone know of a way to test
for
> infinity, nan and denormalized, or to recompress a float into different
word
> size (float16 e.g.) - without reinterpreting the float as an int?
Yep:
int _fpclass(double);
BTW I tend to write this:
int x = ( int & ) f;
instead of:
int x = * ( int * ) &f;
Any known difference ?
Pierre
|
|
From: Alen L. <ale...@cr...> - 2003-12-29 08:14:03
|
> Or you could ask them to come up with a way of doing the same thing cleanly, > with no loss in performance, and see how far they get. ;) No need to mention performance at all. Does anyone know of a way to test for infinity, nan and denormalized, or to recompress a float into different word size (float16 e.g.) - without reinterpreting the float as an int? Alen |
|
From: Neil S. <ne...@r0...> - 2003-12-29 02:27:08
|
> 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. Thankfully, compiler vendors do generally define these things, although they might not always put them in the manual. Perhaps this has something to do with the fact that they have someone to answer to (their customers) if they don't provide useful functionality. > 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. That's why I said "this is a case where", rather than making a blanket statement. ;) > 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". Thing is, they could make it clean if they had any interest at all in practical matters, but they don't, so I have no sympathy for them. > 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! =) Or you could ask them to come up with a way of doing the same thing cleanly, with no loss in performance, and see how far they get. ;) - Neil. |
|
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
|
|
From: Neil S. <ne...@r0...> - 2003-12-28 14:26:24
|
> Of course, no one actually answered the question. I > restated, I'll see what nits they pick with my new question. *sigh* You won't get a proper answer because they have nothing that will help you. The C and C++ standards are retarded in the sense that they have, increasingly over the years, tried to improve platform-independence by tightening up binary compatibility issues, which is 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. So you end up with a set of rules based on the notion that you cannot assume very much about anything at all, such as the relative alignment issues of floats and ints, or even crazy things like a 32 bit int not necessarily being able to represent the data in a 32 bit float. For example, the three 'issues' that were mentioned on comp.std.c *do not actually happen* on any implementations they know of. In other words, the law is an ass. 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. This might reduce theoretical binary compatibility, but will not harm actual binary compatibility one bit, and will at least provide some rules which are compatible with what people actually do. 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. 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. Incidentally, when someone starts asking you to define 'works', you know nothing good will come out of the discussion. ;) - Neil. |
|
From: Daniel V. <vo...@ep...> - 2003-12-28 12:43:11
|
As a follow up, We were seeing the odd behaviour with variants of gcc 3.1 we used for the Linux64 and Mac port. The 3.3 series of gcc packs the same way as VS.NET and 2.95.3 so I assume it was a regression. I couldn't find anything in the documentation but Microsoft confirmed that VS.NET leaves the padding on base types untouched when allocating space for new members in the derived type. -- Daniel, Epic Games Inc. > -----Original Message----- > From: gam...@li... > [mailto:gam...@li...] On > Behalf Of Daniel Vogel > Sent: Wednesday, December 24, 2003 8:36 PM > To: gam...@li... > Subject: [GD-General] packing fun > > Packing fun. > > // both gcc 3.0 and VS.NET support the pack pragma > #pragma pack(4) > > struct Alice > { > int Integer1; > char Char1; > }; > > struct Bob : Alice > { > char Char2; > }; > > gcc 3.0 > sizeof(Alice)==sizeof(Bob)==8 and funnier enough, > STRUCT_OFFSET(Char2) < > sizeof(Alice) > > VS.NET 2003 > sizeof(Alice)==8, sizeof(Bob)==12 > > Is anyone aware of in-detail documentation on variable > packing for both gcc > and VS.NET? > > Thanks, > > -- Daniel, Epic Games Inc. > > > > ------------------------------------------------------- > This SF.net email is sponsored by: IBM Linux Tutorials. > Become an expert in LINUX or just sharpen your skills. Sign > up for IBM's > Free Linux Tutorials. Learn everything from the bash shell > to sys admin. > Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click > _______________________________________________ > Gamedevlists-general mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-general > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=557 > |
|
From: Colin F. <cp...@ea...> - 2003-12-28 06:14:11
|
>>> Oy, freakin' language lawyers. I posted to comp.std.c about >>> this, and they followups basically focused on these two things: >>> >>> - reading a float back as an int is ILLEGAL!!! UNCLEAN, WE CAST >>> THEE OUT!!! >>> >>> - I said "type alias" when the correct terminology is >>> "type punning". I'm such a retard. In the End Days they will be judged as they have judged, and there will be weeping and gnashing of teeth. Yea, even the floats will be read back as ints in the vortex of chaos, where the C specification will be engulfed in a lake of fire until time itself is vaporized. Or maybe not. In any case, Google seems to have a lot of relevant links. (keywords: "type punning") I won't pretend to understand the subject, but these links looked interesting: http://www.talkaboutprogramming.com/group/comp.lang.c.moderated/messages/26015.html http://www.ethereal.com/lists/ethereal-dev/200309/msg00342.html http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_283.htm Hee, hee! "clean up a bunch of type punning warnings" in Quake 2: http://www.quakeforge.net/cgi-bin/viewcvs.cgi/quake2/src/cmd.c http://zuul.quakeforge.net/list-archives/quake2-cvs/2003-July/000243.html |
|
From: Brian H. <ho...@py...> - 2003-12-27 20:09:37
|
Oy, freakin' language lawyers. I posted to comp.std.c about this, and they followups basically focused on these two things: - reading a float back as an int is ILLEGAL!!! UNCLEAN, WE CAST THEE OUT!!! - I said "type alias" when the correct terminology is "type punning". I'm such a retard. Of course, no one actually answered the question. I restated, I'll see what nits they pick with my new question. *sigh* Brian |
|
From: Colin F. <cp...@ea...> - 2003-12-27 00:22:57
|
The fact that the C99 spec is $18, and the C++03 spec is $273,
has "conspiracy" written all over it!
Nobody buys the *latest* (Mwoohahahaaaa!) C++ specifications,
and, WHAM!, [insert greatest horror here] falls upon the Earth!!
(Screaming in terror) "C++ is made of people!!!"
P.S.: My "Faster Than Light" technology relies on type aliasing,
so naturally I had an interest in seeing that the space
aliens didn't infiltrate ANSI and change the C++ specification.
But my robots tell me that if I would just up my meds
that things would have a way of working themselves out for
the best. I think they can't handle the truth, which is
"out there", maybe in the C++03 specification.
|
|
From: Brian H. <ho...@py...> - 2003-12-26 23:05:14
|
> (specifically, the C++ spec says that the compiler can assume no > aliasing). The C spec implicitly states this as well, by itemizing the list of allowable aliases. Brian |
|
From: Neil S. <ne...@r0...> - 2003-12-26 22:56:14
|
> No, I misspoke, it's $273. That is not a typo. > > http://webstore.ansi.org/ansidocstore/product.asp?sku=ISO%2FIEC+14882% > 3A2003 Ah, that's the new C++0x (now called C++03) standard, which was recently published. Most compilers are still catching up on the 1998 standard, which they are still selling for $18: http://webstore.ansi.org/ansidocstore/product.asp?sku=INCITS%2FISO%2FIEC+148 82%2D1998 - Neil. |
|
From: Tom H. <to...@ve...> - 2003-12-26 22:11:51
|
I don't have access to it, but this article supposedly goes into this topic in some detail. http://www.ddj.com/documents/s=880/ddj0010d/0010d.htm Tom |
|
From: Tom H. <to...@ve...> - 2003-12-26 22:10:50
|
At 01:01 PM 12/26/2003, you wrote: >Turns out it is. An assignment expression or function call is treated >as a "void expression" which is evaluated specifically for its side >effects and thus should count as a full expression and, by extension, >as a sequence point. > >So if this chokes an optimizer: > >x = * ( int * ) &f; > >Due to an assignment that occurs on 'f' earlier not being done until >after the assignment to 'x', then it is the optimizer's fault, and not >the programmers. Maybe someone else on the list can confirm what we've been talking about off-list. This problem only exists if the "Assume no Aliasing" compiler optimization is turned on. My understanding is that this optimization tells the compiler that it is ok to break the rules. If the programmer then uses aliasing after telling the compiler to assume he isn't, then I would call this a programmer error ;) The sticky part is, I believe this optimization is defaulted to on in most release build configurations, so it's one of those things that most programmers probably aren't aware of. In one of the many threads on this subject, it has been said that the C++ spec has something in it that allows for this optimization (specifically, the C++ spec says that the compiler can assume no aliasing). The end result would be that writing the above code in C++ is illegal with or without the optimization turned on. Anyone have a copy of the C++ spec that they can search and post relevant portions? >Not to say that a programmer shouldn't be aware of this stuff and deal >with it properly, of course =) Agreed. Tom |
|
From: Daniel V. <vo...@ep...> - 2003-12-26 21:26:13
|
> No, I misspoke, it's $273. That is not a typo. > > http://webstore.ansi.org/ansidocstore/product.asp?sku=ISO%2FIEC+14882% > 3A2003 Wow, the original 1998 version of the C++ standard was only ~$20 (I bought it three times, don't ask). Sad to see them bumping up the price by an order of magnitude for the 2003 revision. -- Daniel, Epic Games Inc. |
|
From: Brian H. <ho...@py...> - 2003-12-26 21:16:53
|
>> $18 from ansi.org. The C++ standard is $183. I think that sums >> up the differences between the two languages very succinctly =3D) >> > > I'm pretty sure the C++ standard is $18 as well. No, I misspoke, it's $273. That is not a typo. http://webstore.ansi.org/ansidocstore/product.asp?sku=3DISO%2FIEC+14882% 3A2003 The C99 spec is only $18: http://webstore.ansi.org/ansidocstore/product.asp?sku=3DINCITS%2FISO%2FI EC+9899%2D1999 Brian |
|
From: Neil S. <ne...@r0...> - 2003-12-26 21:10:02
|
> $18 from ansi.org. The C++ standard is $183. I think that > sums up the differences between the two languages very succinctly =) I'm pretty sure the C++ standard is $18 as well. Although the language is at least 10 times more complicated than C. ;) - Neil. |
|
From: Brian H. <ho...@py...> - 2003-12-26 21:01:20
|
> The only snafu is Appendix C's list of sequence points, where it > says that a "full" expression is a sequence point, but I'm not > quite sure if an assignment is considered a full expression (known > full expressions are expressions used in a return; selection > statement; function calls; and "the expression statement in an > expression"). Turns out it is. An assignment expression or function call is treated as a "void expression" which is evaluated specifically for its side effects and thus should count as a full expression and, by extension, as a sequence point. So if this chokes an optimizer: x =3D * ( int * ) &f; Due to an assignment that occurs on 'f' earlier not being done until after the assignment to 'x', then it is the optimizer's fault, and not the programmers. Not to say that a programmer shouldn't be aware of this stuff and deal with it properly, of course =3D) Brian |
|
From: Brian H. <ho...@py...> - 2003-12-26 20:51:36
|
On Fri, 26 Dec 2003 21:43:52 +0200, Eero Pajarre wrote: > Brian Hook wrote: > > >> About a year and a half ago there was a fairly major brouhaha on >> the algorithms list about this line of code: >> >> int x =3D * ( int * ) &somefloat; >> >> >> Now, let's push aside endianess and size issues, the concern was >> that since there was "type-aliasing" that Something Bad could >> happen. Something Bad, of course, being a rather ambiguous >> statement. >> >> I'm aware of all the bad things that can happen if you have type- >> aliasing in conjunction with pointer aliasing, which is related, >> but that one line above doesn't seem like it should be bad _with >> a legal C compiler_. >> >> The major concern are optimizations that the compiler may make >> that affect order. For example: >> >> somefloat =3D 1.0f; >> x =3D * ( int * ) &somefloat; >> >> >> In theory, a heavily optimizing C compiler would see that the >> assignment to somefloat should not affect the assignment to x >> since they are incompatible types, which may allow it to decide >> to assign to somefloat _after_ the assignment to x. >> >> But that would be illegal. The C specification states that the >> end of every expression is a sequence point, and thus the >> assignment to somefloat MUST be flushed before any subsequent >> statements are executed. >> > I have understood sequence points quite differently... > > > I see them as rules on what I should do, not as promises what the > compiler will do. >From 5.1.2.3.2: "Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,10) which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place." That seems pretty clear to me, which is the basic fundamental rule as to why the whole aliasing thing has been somewhat puzzling to me. The language seems to state that: f =3D 1.0f; y =3D * ( int * ) &f; The only snafu is Appendix C's list of sequence points, where it says that a "full" expression is a sequence point, but I'm not quite sure if an assignment is considered a full expression (known full expressions are expressions used in a return; selection statement; function calls; and "the expression statement in an expression"). Brian |
|
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
|