Associativity and Commas - a plea for help! 
Author Message
 Associativity and Commas - a plea for help!

(Sorry if this has been sent twice, but i`m using dejanews.com, which
sucks hard.)

Hi!
I`m a fairly strong C programmer, but i have a few queries that i`m
sure someone here can help me with. I`m really after
short explanations, a ptr to an on-line tutorial or book that will
explain.

1) The comma operator.  I dont have any C books in front of me, but
aren`t comma operators used to specify the execution order of a series
of steps (expressions?). I`ve used :

 ...
 for (i=0,j=28;i<100;i++)
 ...

but only in for loops.  Does it have any other uses? ( I dont mean
seperating parameters to functions, initialising arrays etc, i mean
specifically in specifying order of execution. I dont see any examples
that i understand. Can you use commas to solve problems like :

i = j + j++ + j;

where the compiler is free to evaluate the expression however it wishes?

2) Left/right associativity. I sort of understand why :

a = *p++;

is taken to mean

a = *p;
p++;

But why isnt the * operator higher? Basically, i`m unsure of the
`interaction` between precedence and associativity.
How can i guarantee that my brain can work through examples of this on
paper in the same way the compiler works it out. I`ve not yet read a
good definition of associativity. Does anyone have any tricks or
methods they want to share? Or is it really simple and i`m missing the
point and over-complicating it all?

Hopefully someone out there has been there and knows what i`m talking
about, and can help. I seem to be well beyond beginners level, but some
of the stuff i see when i browse these groups or read `C/C++ Journal`
and `Dr Dobbs` looks scary too!

Regards,
Alex. (pallex at rocketmail dot com)

Sent via Deja.com http://www.*-*-*.com/
Share what you know. Learn what you don't.
--



Sun, 10 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

[To the moderator: I'm mailing you this directly because my newsserver
has been misconfigured and appears not to be letting me post directly
to moderated groups. Thanks -sunil]

Quote:

> 1) The comma operator.  I dont have any C books in front of me, but
> aren`t comma operators used to specify the execution order of a series
> of steps (expressions?). I`ve used :

>  ...
>  for (i=0,j=28;i<100;i++)
>  ...

> but only in for loops.  Does it have any other uses? ( I dont mean
> seperating parameters to functions, initialising arrays etc, i mean
> specifically in specifying order of execution. I dont see any examples
> that i understand. Can you use commas to solve problems like :

Yes, you can certainly use the comma operator for things other than
for loops. The comma is a sequence point, which basically means that
any side-effects are guaranteed to be complete by then you "move past"
the comma operator.

The C FAQ has examples of what is perhaps the most common use of this
operator (function-like macros).

Quote:
> i = j + j++ + j;

> where the compiler is free to evaluate the expression however it wishes?

The compiler has even more freedom than that, it can do whatever it
likes with that expression. Essentially, as per the C standard what
happens here is "undefined behaviour". IOW, anything could happen.
Again, the C FAQ deals with this in greater depth.

Quote:
> 2) Left/right associativity. I sort of understand why :

> a = *p++;

> is taken to mean

> a = *p;
> p++;

It actually means

        a = *(p++);

The ++ operator takes precedence over the * operator. If you want to
increment the value actually pointed to instead, you should do

        a = (*p)++;

This is a precedence issue, it has nothing to do with associativity.
Associativity comes about primarily when you have an instance of two
adjacent operators having the same precedence.

Quote:
> But why isnt the * operator higher?

It's the way the language was originally designed. Seriously, it's
more "useful" to have the precdence levels this way - it just crops up
more often in code. C isn't Lisp. :)

Quote:
> Basically, i`m unsure of the
> `interaction` between precedence and associativity.
> How can i guarantee that my brain can work through examples of this on
> paper in the same way the compiler works it out.

Every good textbook or reference manual will have a precedence table
in it. Some common ones, like this one, are worth committing to memory
via constant use. Just write a few small example test programs and
make sure you fully understand what's going on.

Quote:
> I`ve not yet read a
> good definition of associativity. Does anyone have any tricks or
> methods they want to share? Or is it really simple and i`m missing the
> point and over-complicating it all?

It might be worth your taking a look at "C - A Reference Manual", 4th
Edn, Samuel P Harbison and Guy L Steele Jr. A lot of this sort of
stuff is fully explained in there.

--
{ Sunil Rao }
"...certainly no beast has essayed the boundless, infinitely
 inventive art of human hatred. No beast can match its range and
 power." - Arundhati Roy, "The God of Small Things", 1997.
--



Sun, 10 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

writes

Quote:
>Hi!
>I`m a fairly strong C programmer, but i have a few queries that i`m
>sure someone here can help me with. I`m really after
>short explanations, a ptr to an on-line tutorial or book that will
>explain.

>1) The comma operator.  I dont have any C books in front of me, but
>aren`t comma operators used to specify the execution order of a series
>of steps (expressions?). I`ve used :

One problem here is that a comma is both an operator and a punctuator
depending on context.  Most of the uses are punctuators, i.e. simply
separating out several items (such as the elements of an argument list).
In this context it has nothing to say about the order of evaluation.

Within an expression it is a sequence operator and requires completion
of all the side effects of evaluating the left operand before evaluation
of the right operand.  It actually has relatively little use because
virtually every use can be replaced by writing distinct statements
separated by semicolons.

The place I use it is where I want to express that something is
conceptually one action even though it may require evaluation of two
expressions sequentially. E.g.:

int * ptr = malloc(somestorage);
/* code */
free(ptr), ptr = 0; /* release the memory and place the pointer in a
safe state. */

Quote:

>i = j + j++ + j;

Not really.  In such cases you need to write what you mean.  Even
without the undefined behaviour of writing to storage that is being read
for another purpose, such lines have problems with order of evaluation
which are not going to be resolvable with sequence operators.

Quote:

>where the compiler is free to evaluate the expression however it wishes?

Or anything else it elects to do because you read (evaluate) j for
purposes other than writing to it.

Quote:

>2) Left/right associativity. I sort of understand why :

>a = *p++;

>is taken to mean

>a = *p;
>p++;

You are confusing associativity which in the computing context refers to
the order in which multiple successive operators of the same class are
evaluated, with precedence that determines the order in which different
operators are evaluated.  Note that it is subexpressions that are
subject to no defined order of evaluation though there are rules about
ordering of evaluation of operators (confusing? yes but the only way to
clarify that confusion is by working at it)

Quote:
>But why isnt the * operator higher? Basically, i`m unsure of the
>`interaction` between precedence and associativity.
>How can i guarantee that my brain can work through examples of this on
>paper in the same way the compiler works it out. I`ve not yet read a
>good definition of associativity. Does anyone have any tricks or
>methods they want to share? Or is it really simple and i`m missing the
>point and over-complicating it all?

Look:

a=b=c=0;

zeroes a, b and c because assignment associates right to left.  If it
worked left to right a would take the value of b, b that of c and c
would become zero.

double a=1.0, b=2.0, c=3.0;

a = a/b/c;

is required to evaluate a divided by b and then divide the result by c.
 a = a/b*c;
is required to evaluate  (a divided by b) times c

Both these are because multiplicative operators (that includes division)
associate left to right.

a = a+ b/c;
requires that b is divided by c and the result is added to a because
additive operators (also associating left to right) have lower
precedence than multiplicative ones.

and all the above work because assignment has a lower precedence than
arithmetic operators.

Quote:

>Hopefully someone out there has been there and knows what i`m talking
>about, and can help. I seem to be well beyond beginners level, but some
>of the stuff i see when i browse these groups or read `C/C++ Journal`
>and `Dr Dobbs` looks scary too!

Well perhaps you should class your self as an experienced novice:)  At
least you know enough to ask.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Sun, 10 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

It seems to me that both your questions indicate that you would like
to be clever in your programming, and use the facilities of the
language to the limit. If that is the case (and maybe it isn't),
be warned that it is a bad idea. Don't write clever code, write
clear one. I will address that for both questions of yours.

Quote:

> 1) The comma operator.  I dont have any C books in front of me, but
> aren`t comma operators used to specify the execution order of a series
> of steps (expressions?). I`ve used :

>  ...
>  for (i=0,j=28;i<100;i++)
>  ...

> but only in for loops.  Does it have any other uses?

Yes, most often to write multi-statement macros, ONLY in the cases
where all the statements are simple exressions, not declarations or
loops. You can write a parenthesized expression separating
sub-statements with commas, and even "return a value" from a macro.
See the comp.lang.c FAQ, #10.4, #10.26.

Usually, even this is not such a great idea (to quote Kernighan and
Pike from memory, "the C preprocessor is a blunt tool"). FAQ #10.26
gives an example and discusses the disadvantages.

Another possible use for comma is when the order of operations is
very clear, such as in the swap (UNTESTED):

void swap(int *x, int *y)
{
    int tmp;
    tmp = *x, *x = *y, *y = *x;

Quote:
}

I personally don't see any advantage in this over 3 separate statements.

Quote:
> ( I dont mean seperating parameters to functions, initialising
> arrays etc, i mean specifically in specifying order of execution.

Those commas are not comma operators, and do not guarantee left to
right evaluation.

Quote:
> I dont see any examples
> that i understand. Can you use commas to solve problems like :

> i = j + j++ + j;

> where the compiler is free to evaluate the expression however it
> wishes?

Do you mean

i = j, i += j, j++, i += j;

Even though you can, there is no need to do that. Just write separate
statements - the code will be easier to read, understand, and maintain.

Quote:
> 2) Left/right associativity. I sort of understand why :

> a = *p++;

> is taken to mean

> a = *p;
> p++;

Or

a = *p, p++;

;-)

Quote:

> But why isnt the * operator higher?

Indirection (*) is at the same level of precedence as the increment
and decrement operators. Why? I can venture a guess regarding this
particular case: it is such a common thing to increment a pointer...

Quote:
> Basically, i`m unsure of the `interaction` between precedence and
> associativity.

When precedence is the same, the associativity rules are used.

Quote:
> How can i guarantee that my brain can work through examples of this on
> paper in the same way the compiler works it out.

There are two bad ways, a very bad way, and a good way. The good way
is to always use parentheses to remove any ambiguity. This doesn't
help when you have to read code which doesn't use parentheses (I hate
that). Then you are stuck with the bad ways. The very bad way is to
remember all the precedence and associativity rules. The bad way that
I use is to consult a reference. I do that because I don't think it is
worth my while to use the other bad way, which is to remember that:

1) all binary operators except assignments are left-associative;
2) assignments and the ternary conditional are right-associative;
3) the unary and postfix operators are right-associative.

The last rule merely says that *p++ is *(p++) and not (*p)++. Harbison
& Steele suggest remembering that the postfix operators have higher
precedence than the prefix unary operators.

And once again, don't abuse either the comma operator or the
precedence rules. There is nothing wrong with using separate
statements, or with putting parentheses wherever they remove any doubt
about the order of evaluation. Don't be clever.

--


"Life's not fair, but the root password helps." [S.Travaglia]
--



Sun, 10 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

writes, in part:

Quote:
>2) Left/right associativity. ...  Basically, i`m unsure of the
>`interaction` between precedence and associativity.

It might help to keep in mind that the C language as defined by
the C standard has neither precedence nor associativity.

The trick here is that C expressions are "parsed" according to a
"grammar".  Consider an expression like:

        a * b + c * d

This might be grouped the same as any of:

        ((a * b) + c) * d       /* we do not want this one */
        a * (b + (c * d))       /* nor this one */
        (a * (b + c)) * d       /* nor this one */

or various other possibilities; but we *want* it to come out as:

        (a * b) + (c * d)       /* this is the one we really want */

The question then is, how do we arrange for a compiler to do this?

The C standard uses a "fully factored" grammar.  One small and
highly simplified subset of this grammar is:

        mulexp:
                identifier
                mulexp * identifier

        expression:
                mulexp
                expression + mulexp

Now, using this grammar, your job is to see how:

        a * b + c * d

could possibly be an "expression".  Note that a, b, c, and d are
"identifiers".  So for the whole line above to be an "expression",
it had better begin with a mulexp, possibly followed by a "+" and
then another mulexp.

Is there a mulexp there, possibly followed by a "+"?  Well, "a"
is an identifier, and a mulexp can be an identifier.  There is
something after "a", and it is not a "+", but rather a "*", so
it fits the first two parts of "mulexp * identifier".  Is the
thing after the "*" an identifier?  It is "b", so yes.

That means "a * b" is a mulexp.  The next thing is a "+", which
cannot be part of a "mulexp" -- only identifiers and "*"s can go
into "mulexp"s.  So we have completed matching one "mulexp".

Now there is still a "+", so we can try the "expression + mulexp"
line, having matched the first "expression" against "mulexp".  That
means whatever comes after the "+" had better be another "mulexp".
Is it?

By the same reasoning as for "a * b" above, "c * d" is a valid
mulexp.  That means "a * b" is a mulexp, which is an expression
(by the first rule -- "expression: mulexp"), and "c * d" is a
mulexp, and the whole thing is an "expression" by the
"expression + mulexp" rule.

In order to get here, we were forced to "bind up" the "a * b" as
a single unit, and then "bind up" the "c * d", and only then "bind
up" the "expression + mulexp".  That means that to compute the
value of the whole thing, we will have to add "a * b" and "c * d",
not do something like "a * (b + c) * d".

The C Standard's grammar achieves the desired grouping without
using either precedence or associativity.  There is simply no other
way to turn "a * b + c * d" into an "expression".  If you try to
group the "b + c" first, the "a *" and "* d" will not match the
grammar rules, so you would have a syntax error.

Quote:
>How can i guarantee that my brain can work through examples of this on
>paper in the same way the compiler works it out.

This is where precedence and associativity come in.  If you read
the actual C Standard's grammar, you will see that I left out a
lot of detail.  An "expression" is actually an "assignment-expression"
which goes through things like "conditional-expression" and
"logical-OR-expression" and so on long before it gets to addition
and multiplication; after that it goes on through things like
"cast-expression" and "unary-expression" and "postfix-expression"
before it ever gets to "identifier".

It is far easier to remember that, given:

        a * b + c * d

the multiplication has "higher precedence".  We all had some form
of "My Dear Aunt Sally" (Multiplication and Division, then Addition
and Subtraction) drummed into us in primary school.  We all know
to group this as "a * b", then "c * d", then "+", because we have
been doing it for years.

Precedence works for more than just */ and +-, and we can write an
equivalent grammar using precedence rules to make sure we get the
right grouping.  This is easier to *remember*.

Precedence, however, only handles things like "a * b + c * d".
What about "a / b / c"?  This could be either: (a / b) / c, or
a / (b / c).  The results will be different.  So we need one more
grouping rule, and that one is "associativity".

Things that are left-associative, we group (by mentally adding
parentheses) on the left:

        a / b / c

is left-associative, so it "means":

        (a / b) / c

Things that are right-associative, we group on the right:

        w = x = y

"means"

        w = (x = y)

Like precedence, we fall back on associativity only when there
are two or more ways to read something.  Until then -- such as,
if precedence tells us to read something only one way -- we can
ignore it.

The pitfall in "thinking about" expressions in terms of precedence
and associativity is that it leads people to think that, if the
expression has to *group* that way, it has to *evaluate in that
order*.  This is not true in C.  The best illustrations occur
when using functions that print messages when they are called:

        x = a() * b() + c() * d();

Suppose a(), b(), c(), and d() all print "in a", "in b", etc.,
when they are called.  Using either the Standard C grammar, or
a simpler-for-people grammar with precedence and associativity
rules, we know that this has to be *grouped as*:

        - collect up a() and b(), and multiply
        - collect up c() and d(), and multiply
        - add

but the compiler could implement this by calling c() first, then
a(), then b(), then d() -- or any other order -- as long as it
produces the same final number to put into "x".

Thus, precedence and associativity exist only in our heads, not
in the Standard C language; and they do not determine evaluation
order.
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc


--



Mon, 11 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!
In a superb article, Chris Torek writes:

Quote:
> Precedence, however, only handles things like "a * b + c * d".
> What about "a / b / c"?  This could be either: (a / b) / c, or
> a / (b / c).  The results will be different.  So we need one more
> grouping rule, and that one is "associativity".

> Things that are left-associative, we group (by mentally adding
> parentheses) on the left:
>    a / b / c
> is left-associative, so it "means":
>    (a / b) / c

> Things that are right-associative, we group on the right:
>    w = x = y
> "means"
>    w = (x = y)

There are two more things to be said here.

The first is that the standard does not specify associativity directly,
any more than it does precedence.  Rather, the grammar of expressions
is written in such a way as to determine the associativity.  Note the
assymetric grammatical rule in the simplified grammar that Chris
provided:

        expression:
                mulexp
                expression + mulexp

This makes + left-associative.  If the last line was "mulexp + expression",
+ would be right-associative.

The second thing is a reminder that this now common usage of "associa-
tivity" is completely at variance with the mathematical meaning of the
term, making another possible source of confusion.  If it matters whether
something is "left-associative" or "right-associative", then to a
mathematician, it is *not* associative, or to put it another way, *does
not have* associativity.  If an operator *is* associative in the
mathematical sense, this means that both groupings are guaranteed to
produce equivalent results.

C operators that are in fact associative in the mathematical sense
include the comma operator (,) and the logical operators (&& and ||).
The C grammar makes each one left- or right-associative, but in the
cases of these operators the result of the expression would be the same
if the opposite choice had been made in the grammar.  That is, x&&y&&z
is required to parse like (x&&y)&&z, but the result would be the same
if it had been required to parse like x&&(y&&z).
--
Mark Brader   "What a strange field.  Studying beings instead of mathematics.
Toronto        Could lead to recursive problems in logic."

My text in this article is in the public domain.
--



Mon, 11 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

Quote:

> (Sorry if this has been sent twice, but i`m using dejanews.com, which
> sucks hard.)
> Hi!
> I`m a fairly strong C programmer, but i have a few queries that i`m
> sure someone here can help me with. I`m really after
> short explanations, a ptr to an on-line tutorial or book that will
> explain.
> 1) The comma operator.  I dont have any C books in front of me, but
> aren`t comma operators used to specify the execution order of a series
> of steps (expressions?). I`ve used :
>  ...
>  for (i=0,j=28;i<100;i++)
>  ...
> but only in for loops.  Does it have any other uses? ( I dont mean
> seperating parameters to functions, initialising arrays etc, i mean
> specifically in specifying order of execution. I dont see any examples
> that i understand. Can you use commas to solve problems like :
> i = j + j++ + j;
> where the compiler is free to evaluate the expression however it wishes?

One way I sometimes use it is in conditional statements:

if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) {

which I would need to write as two separate test without a , operator.
This saves whitespace on the left.

As others have answered, your example is broken beyond repair,
and a ',' won't help. Why not write i = 3*j++ ?

Michiel Salters
--



Mon, 11 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!


Quote:
>but the compiler could implement this by calling c() first, then
>a(), then b(), then d() -- or any other order -- as long as it
>produces the same final number to put into "x".

Or even a different one (for example where the return values of a() and
b() depend on a global value (more options if they have parameters that
include pointers) that they modify.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Mon, 11 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!


Quote:
>One way I sometimes use it is in conditional statements:

>if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) {

>which I would need to write as two separate test without a , operator.
>This saves whitespace on the left.

??? but the result of doing that is to evaluate (for side effects) the
left operand but return the value of the right operand.

Quote:

>As others have answered, your example is broken beyond repair,
>and a ',' won't help. Why not write i = 3*j++ ?

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Tue, 12 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

Quote:



> >One way I sometimes use it is in conditional statements:
> >if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) {
> >which I would need to write as two separate test without a , operator.
> >This saves whitespace on the left.
> ??? but the result of doing that is to evaluate (for side effects) the
> left operand but return the value of the right operand.

Yes - what's so strange about that? The &result suggests that result may be
modified, and that's what I intended. The idea is that ExpensiveTest will
set result.member . Now, if that is a function not under my control, or it is
used in many places, I can't just make it return result.member . This form
does allow me to test the "pseudo-return" value.

An example would be a database read. I can't change the database access
functions, they often put their results in caller-allocated memory, and
they might be quite expensive.

Michiel Salters
--



Sat, 16 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

Quote:




>> >One way I sometimes use it is in conditional statements:

>> >if( TestNeedstobeDone && ExpensiveTest(&result),result.member==somevalue) {

>> >which I would need to write as two separate test without a , operator.
>> >This saves whitespace on the left.
>> ??? but the result of doing that is to evaluate (for side effects) the
>> left operand but return the value of the right operand.

>Yes - what's so strange about that? The &result suggests that result may be
>modified, and that's what I intended. The idea is that ExpensiveTest will
>set result.member . Now, if that is a function not under my control, or it is
>used in many places, I can't just make it return result.member . This form
>does allow me to test the "pseudo-return" value.

But remember that the comma operator has the lowest precedence, lower
even than &&, so your snippet above is parsed as (making the obvious
abbreviations for brevity's sake).

   if ((T && E(&r)), r.m==s)

rather than

   if (T && (E(&r), r.m==s))

which is what you seem to want.

Regards,

                          -=Dave
Just my (10-010) cents
I can barely speak for myself, so I certainly can't speak for B-Tree.
Change is inevitable.  Progress is not.
--



Sun, 17 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!


Quote:
>Yes - what's so strange about that? The &result suggests that result may be
>modified, and that's what I intended. The idea is that ExpensiveTest will
>set result.member . Now, if that is a function not under my control, or it is
>used in many places, I can't just make it return result.member . This form
>does allow me to test the "pseudo-return" value.

OK.  I see what you are doing, it is just that this kind of overly
complicated statement frequently leads to trouble.  Why not move
everything to the left of the sequence operator to before the if?

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Sun, 17 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!
Thanks to everyone who posted a response. To save me sending 5 messages
i`ll
take the liberty of replying here, in one go!

Sunil Rao:

Quote:
> The comma is a sequence point, which basically means that

any side-effects are guaranteed to be complete by then you "move past"
the comma operator.

Which is much more clear than any book i`ve read about it. I had
no idea it was that simple! Cheers!

Oleg Goldshmidt:

Quote:
> It seems to me that both your questions indicate that you would like
> to be clever in your programming, and use the facilities of the
> language to the limit. If that is the case (and maybe it isn't),
> be warned that it is a bad idea. Don't write clever code, write
> clear one.

No, I hate needlessly clever code too. I always try to write clearly,
show
precedence with brackets, use curly braces for one line `if` conditions
where they`re not needed etc.  I wanted to know so i could decode
other peoples code!

Quote:
> Another possible use for comma is when the order of operations is
> very clear, such as in the swap (UNTESTED):

> void swap(int *x, int *y)
> {
>    int tmp;
>     tmp = *x, *x = *y, *y = *x;
> }

> I personally don't see any advantage in this over 3 separate

statements."

Me neither, and i`d never write it that way.

Quote:
> When precedence is the same, the associativity rules are used.

Thats all i need to know! Thanks!

Chris Torek:

Wow! Thanks for that (your post about expression parsing etc).
Basically
i`ve occasionally seen hairy looking recursive code for evaluating
expressions,
and even `simple` ones which dont have variables look reasonably
intimidating,
and your little essay prompted me to go and buy a book on data
structures,
algorithms etc which covers it.

Michiel Salters:

Quote:
> i = j + j++ + j;
> where the compiler is free to evaluate the expression however it

wishes?

Quote:
>As others have answered, your example is broken beyond repair,
>and a ',' won't help. Why not write i = 3*j++ ?

Not the same. i=3*j++ wont necessarily work (undefined behaviour). If
you
evaluate from left to write here, trying with j=1, you get:

i = 1 + 1 + 2

But i agree, i wasnt suggesting you should actually write code like
that;
i just wondered if it was a case where the comma operator would/could
help, and it seems the answer is that it would, but that its better to
just write individual lines.

----------

There was also a bit of a debate about:

Quote:
> if( TestNeedstobeDone && ExpensiveTest

(&result),result.member==somevalue) {

which I thought was just saying :

if ( (TestNeedstobeDone && ExpensiveTest(&result)) &&
          (result.member==somevalue) ) {

or even more clearly :

if (TestNeedstobeDone && ExpensiveTest(&result))
{
        if (result.member==somevalue)
        {

(Ie, the comma (sequence) operator and the boolean AND (and OR)
operators both deal
with this expression from left to right, guaranteeing that we wont get
a page fault
(or whatever) when we dereference the (undefined, almost certainly
meaningless)
`result` variable)

but which provoked the response :

Quote:
> OK.  I see what you are doing, it is just that this kind of overly
> complicated statement frequently leads to trouble.  Why not move
> everything to the left of the sequence operator to before the if?

Do you mean as per my second example?

----------

Thanks again for all your help,


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
--



Sun, 17 Feb 2002 03:00:00 GMT  
 Associativity and Commas - a plea for help!

[...]

Quote:
>There was also a bit of a debate about:

>> if( TestNeedstobeDone && ExpensiveTest
>(&result),result.member==somevalue) {

>which I thought was just saying :

>if ( (TestNeedstobeDone && ExpensiveTest(&result)) &&
>      (result.member==somevalue) ) {

>or even more clearly :

>if (TestNeedstobeDone && ExpensiveTest(&result))
>{
>    if (result.member==somevalue)
>    {

But that's not what it says.  It's closer to

   if (TestNeedstobeDone)
      ExpensiveTest(&result);

   if (result.member==somevalue) {

In other words, the comma operator has the lowest precedence.  Of
anything.  So your statement gets parsed as

   if ( (TestNeedstobeDone&&ExpensiveTest(&result)),
         result.member==somevalue )

rather than

   if (TestNeedstobeDone &&
        (ExpensiveTest(&result),result.member==somevalue) )

which appears to be what you want.  If this is what you want, you need
the extra parentheses.

[...]

Quote:
>but which provoked the response :

>> OK.  I see what you are doing, it is just that this kind of overly
>> complicated statement frequently leads to trouble.  Why not move
>> everything to the left of the sequence operator to before the if?

>Do you mean as per my second example?

No, more like mine.  Francis (I think this was his response) thought
you wanted that.  If that is indeed what you want, he's right, the
statement is overly complicated.  If it's not what you want, that just
*proves* the statement is overly complicated.  ;-)

Regards,

                          -=Dave
Just my (10-010) cents
I can barely speak for myself, so I certainly can't speak for B-Tree.
Change is inevitable.  Progress is not.
--



Sat, 23 Feb 2002 03:00:00 GMT  
 
 [ 18 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Help with Associativity

2. UserControl-properties...please help

3. Plea for help in creating bitmap image to file of the screen

4. Pleas help can't see a created view in Access

5. api call pleas help

6. COleDateTime parsing - 2nd plea for help!

7. Pleas Some one help me please save me !!!!!!!!!!!!!!!!!!!!!!!!!!!!

8. Comma operator in #define's (was Re: Usage of comma operator)

9. Bind a DB Grid to a CDaoRecordset Pleas Help

10. BUG VC++ and plea for help

11. help with comma operator (I think)

12. HELP: Comma operator

 

 
Powered by phpBB® Forum Software