Re: GCC not doing the correct thing?
Re: GCC not doing the correct thing?
- Subject: Re: GCC not doing the correct thing?
- From: Domain Administrators <email@hidden>
- Date: Sat, 9 Nov 2002 21:35:50 +0000 (GMT)
Forgive me for my impertinence, but if the example code were to be
"undefined" by definition, we would all be in a lot of trouble. But
this is not so, and the example given makes the argument all the
easier.
Let's review. We have a macro which I will retype as
#define CUBE(A) ((A) * (A) * (A))
And we have a sample parameter given as
*ptr++
Which supposedly renders the expression undefined.
First, let's substitute as the macro preprocessor has to.
((*ptr++) * (*ptr++) * (*ptr++))
This is so patently simple I am surprised - and shocked - others
don't get it. C uses both binding, precedence, and associativity to
define how expressions are broken down and parsed. For example, we
have both prefix and postfix increment and decrement operators, and
we know what the difference is there. In the expression
*ptr++
We know that ptr is dereferenced before it is incremented, because
of the left to right associativity. We also know that * and ++ are
bound before the multiplication operator. What we get is the
following. Let us say that ptr points to an array in memory such as
the following.
A B C D E F G H I J K L M N
It doesn't really matter how the parser evaluates the expression, as
the substituted parameter is always the same. When the first
expression *ptr++ is evaluated, the parser gets "A" and then
increments the pointer to the next address in the array.
When the next expression is evaluated, the pointer is again
dereferenced, giving "B" before incrementing the pointer again. And
so forth.
The end result - no matter what associativity is used - is A * B *
C, with ptr thereafter pointing to the cell with "D" in it.
As stated, C uses both binding, precedence, and associativity. The
rules for binding tell us that * and ++ on ptr get evaluated before
this operand is considered with its operator *. The rules of
associativity tell us that the entire expression will be evaluated
left to right. The rules of precedence are not relevant here, as the
same operator is used throughout.
Dennis Ritchie's original compiler for C, before Steve Johnson's
pccm, was recursive in design, and it is easy to see why he chose
this model. Every expression must be broken down into
sub-expressions, etc., and each of these sub-expressions must be
evaluated first - or according to the above-stated rules.
This is all in the original K/R. We used to have these tables pasted
to our walls - they're that important to know. The thought that
programmers of today not be aware of these very basic rules for
parsing, and think that expressions of the relatively easy CUBE
example given should be "undefined" scares me. The prospect that GCC
or some other compiler get hiccups with something like this shocks
me.
--- "Clark S. Cox III" <email@hidden> wrote: > -----BEGIN PGP
SIGNED MESSAGE-----
>
Hash: SHA1
>
>
>
On Friday, Nov 8, 2002, at 15:51 US/Eastern, Domain Administrators
>
>
wrote:
>
>
> Absolutely nothing. You're right. Even the order of the accesses
>
of
>
> x in x*x*x is defined in the associativity of the language. It
>
has
>
> to be.
>
>
>
> If GCC has problems with this, then we're in trouble. R.
>
>
>
>> What's undefined about the following?
>
>
>
>> cube( (*ptr++) )
>
>
Neither the order of memory fetches or the order of stores is
>
defined.
>
Operator precedence and associativity are irrelevant here. for
>
example,
>
in the following expression (x+y*z), the compiler is allowed to:
>
>
>
fetch all three variables at once, before performing any
>
operations
>
fetch each individual variable as the need arises
>
fetch them in a random order, as long as they are loaded before
>
the
>
actual calculation is performed
>
>
>
In the following example (which is a perfectly legal statement):
>
>
a = x++ + y++ + z++;
>
>
The compiler is only required to:
>
>
1) fetch the values of the three variables
>
2) add them together
>
3) assign the result to a
>
4) increment each of the three variables
>
>
As long as the incrementing happens after the fetching, the
>
compiler is
>
well within it's right to do whatever it pleases (in fact, for
>
whatever
>
reason, step 4 could come between 1 and 2, or between 2 and 3)
>
>
However in this example (which is invokes undefined behavior):
>
>
a = x++ + x++ x++;
>
>
Since the C standard does not specify when the increment takes
>
place
>
(i.e. it only has to take place sometime after the initial value
>
is
>
fetched, but before the next sequence point), the compiler would
>
be
>
well within it's right to compile this as:
>
>
a = x+x+x;
>
x += 3;
>
>
or
>
>
a = (x+1)+(x+1)+(x+1)
>
x += 3;
>
>
or
>
>
a = x;
>
a += x++;
>
a += x++;
>
a += x++;
>
>
Each of which yield different results. So the result of such an
>
expression is "undefined" as per the standard, and in fact it is
>
explicitly stated to be so in the standard.
>
>
- --
>
http://homepage.mac.com/clarkcox3/
>
email@hidden
>
Clark S. Cox, III
>
-----BEGIN PGP SIGNATURE-----
>
Version: GnuPG v1.0.7 (Darwin)
>
>
iEYEARECAAYFAj3MJ58ACgkQd6STocYT1xUF+QCgl5k7j4K3fh+ReOI8tY6l2r7n
>
TZsAnimyRSmzvraP7UeHbCUeZerZFQV1
>
=yh1e
>
-----END PGP SIGNATURE-----
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.