*++p vs ++*p

F

Francis Moreau

Hello,

In my understanding, this 2 expressions are equal since '++' operator
has a higher precedence than '*' operator.

But of course they aren't (I checked with a short test program).

So I'm missing something in the C spec about the evalution of
expressions.

Could anybody give me some hints ?

Thanks
 
R

Ralf Damaschke

Francis said:
Hello,

In my understanding, this 2 expressions are equal since '++' operator
has a higher precedence than '*' operator.

But of course they aren't (I checked with a short test program).

So I'm missing something in the C spec about the evalution of
expressions.

Could anybody give me some hints ?

6.5.3

/unary-expression/: ++ /unary-expression/
/unary-expression/: * /cast-expression/

have the same precedence. Both operators are applied to their
operand which stands at the right of the operator.

-- Ralf
 
C

CBFalconer

Francis said:
In my understanding, this 2 expressions

What two expressions?

(Write "two", not "2". People won't help you if you're lazy.)

If you mean the subject line, then PLEASE include what you're
talking about in the body of your post so we can remember
what you're discussing.

Anyway, both *++p and ++*p are syntax errors. Why? Because
you've failed to include any code context so we can see how
you're using those two expressions. What if you've forgotten
a semicolon? We can't tell from what you've given us.

PLEASE supply the smallest program that demonstrates your
problem. If you're using a Doze debugger, ask on the appropriate
newsgroup where you can get a better one.
 
F

Francis Moreau

Ralf Damaschke said:
6.5.3

/unary-expression/: ++ /unary-expression/
/unary-expression/: * /cast-expression/

have the same precedence. Both operators are applied to their
operand which stands at the right of the operator.

Ah I've been mistaken by this:

http://fr.wikibooks.org/wiki/Programmation_C/Opérateurs

where it looks like ++ precedence is higher than * one.

Now I looked at the spec and I'm wondering where operator precedence
is defined. Does the operator sections are sorted in precedence order
?

Thanks
 
J

James Kuyper

Francis said:
Hello,

In my understanding, this 2 expressions are equal since '++' operator
has a higher precedence than '*' operator.

Yes, but precedence is irrelevant here. The only way to parse *++p is as
*(++p), while ++*p can only be parsed as ++(*p). It's not possible to
parse ++*p in such a way that ++ is applied directly to the 'p' before
applying the '*', because the 'p' is not directly to the right of the
++; the * gets in the way.
 
B

Barry Schwarz

Hello,

In my understanding, this 2 expressions are equal since '++' operator
has a higher precedence than '*' operator.

But of course they aren't (I checked with a short test program).

So I'm missing something in the C spec about the evalution of
expressions.

Precedence indicates how operators bind. It cannot rearrange
operators and change their operands. For each of the two expressions:

What is the operand of the ++ operator?

What is the operand of the * operator?
 
B

Bartc

CBFalconer said:
What two expressions?

(Write "two", not "2". People won't help you if you're lazy.)

You're not allowed to write numbers using numerals now? That's going to get
long-winded for numbers like 41421356237.
 
K

Kaz Kylheku

Hello,

In my understanding, this 2 expressions are equal since '++' operator
has a higher precedence than '*' operator.

There are two forms of the ++ operator, a prefix and postfix.

The prefix ++ operator has exactly the same precedence and associativity as the
prefix * operator. The postfix ++ has a higher precedence, but you are not
using that here.

Precedence doesn't grant operators the power to jump over expressions. I don't
think you misunderstand precedence.

If we have some prefix operators applied to an object:

op1 op2 op3 ... opn obj

it's not the case that the operations are all applied on obj, in order of
some precedence. Rather, it's like this:

op1 (op2 (op3 ... (opn obj) ... ) )

The op1 is done on the expression (op2 ...), and op2 is done
on the expression (op3 and so on.

All the ops have the same precedence, and right-to-left associativity, which is
why opn is applied first, then opn-1 to the result of that and so on, with op1
being applied last.
But of course they aren't (I checked with a short test program).

So I'm missing something in the C spec about the evalution of
expressions.

What you're missing is the fact the order of symbols matters.

There are six ways of scrambling the order of ++, * and p.

All six permutations are different. Three of them have bad syntax, and the
good three have different meaning:

++ * p // (++ (* p)) increment the object pointed at by p
++ p * // ((++ p) * <missing operand>)) bad syntax
* ++ p // (* (++ p)) increment p; dereference new value
* p ++ // (* (p ++)) increment p; dereference old value
p ++ * // ((p ++ ) * <missing operand>)) bad syntax
p * ++ // (p * (++ <missing operand))) bad syntax

The bad syntax cases are exprssion fragments in which * is binary
(multiplication).
 
K

Kaz Kylheku

Precedence doesn't grant operators the power to jump over expressions. I don't
think you misunderstand precedence.

Should be, ``I think you misunderstand precedence.''
 
B

Ben Bacarisse

Bartc said:
You're not allowed to write numbers using numerals now? That's going
to get long-winded for numbers like 41421356237.

One of several recent fakes, I suspect.
 
P

Phil Carmody

Tetsuya said:
Yes, they have the same precedence, but in *++p YOU write the * before
the ++, so the compiler does * then ++.

Except when it doesn't. Which is always.

Phil
 
C

CBFalconer

CBFalconer said:
What two expressions?

(Write "two", not "2". People won't help you if you're lazy.)

Again, this is a troll, and not from me. The path originates in
eternal-september.org
 
F

Francis Moreau

Hello,


[...]
What you're missing is the fact the order of symbols matters.

Ah yes, thanks a lot I think I have understood now.

So if I have this postfix expression:

obj++->id = 0;

It is equivalent to:
(obj++)->id = 0;

And this expression:
++obj->id;

is equivalent to:
++(obj->id);

So now let say the next spec introduce a new unary operator 'opx'
which has a higher precedence than all others unary operators.

how the following expression is evaluated ?

op1 opx op3 obj

Thanks !
 
F

Francis Moreau

Barry Schwarz said:
Precedence indicates how operators bind. It cannot rearrange
operators and change their operands. For each of the two expressions:

What is the operand of the ++ operator?

What is the operand of the * operator?

yes but initialy I thought these two operators didn't have the same
precedence.

What would happen if they didn't have the same precedence ?

thanks
 
F

Francis Moreau

James Kuyper said:
Yes, but precedence is irrelevant here. The only way to parse *++p
is as *(++p), while ++*p can only be parsed as ++(*p). It's not
possible to parse ++*p in such a way that ++ is applied directly to
the 'p' before applying the '*', because the 'p' is not directly to
the right of the ++; the * gets in the way.

Ah ok, does the way to parse is coming from the 'syntax' section of
each operators ?

Thanks
 
I

Ike Naar

So now let say the next spec introduce a new unary operator 'opx'
which has a higher precedence than all others unary operators.

how the following expression is evaluated ?

op1 opx op3 obj

The only possible evaluation order for the above expression is

op1 (opx (op3 obj) )

This order is dictated by the structure of the expression, not
by any precedence order amongst op1, opx and op3.

In fact, all unary prefix operators can be thought of having equal
precedence, the evaluation order is determined by the distance to the operand.

Similarly, all unary postfix operators have equal precedence, and
the evaluation order is determined by the distance to the operand.

In C, unary postfix operators, as a group, have higher precedence than
unary prefix operators as a group.

So, for example, if op1, op2 and op3 are unary prefix operators, and
opx, opy and opz are unary postfix operators, then

op1 op2 op3 obj opx opy opz

is evaluated as:

op1 (op2 (op3 ( ( (obj opx) opy) opz) ) )
 
J

James Kuyper

Francis said:
Ah ok, does the way to parse is coming from the 'syntax' section of
each operators ?

Yes. For any operator that takes a right operand, that operand must be
an expression that lies immediately to the right of the operator. In the
case of ++*p, you have a choice of '*' (which is not an expression, it's
just an operator), or "*p" (which is an expression). You do not have the
choice of using "p" alone as the operand. The same is true if you
replace 'right' with 'left' everywhere in the preceding sentence.

The C standard doesn't use the concept of operator precedence. It uses
grammar productions, instead. However, ith only a few exceptions, the
grammar can be explained using the concept of precedence (the ?:
operator is the main exception). But precedence only matters when there
are two different operators that could operate on the same operand, and
that is only possible if the operand is in a position so it could
otherwise be either the left operand for one operator or the right
operand of the other operator.

For instance, precedence can be used to explain the grammar rule that
requires a + b * c to be parsed as a + (b * c) rather than (a + b) * c.
That's because 'b' lies between the '+' and the '*'. However, there's
not even an option to parse it as either (a + c) * b or b + (a * c),
because 'c' is in the wrong position to be the right operand of '+', and
'a' is in the wrong position to be the left operand of '*'.

Similarly, in the expression "++*p", 'p' is in the wrong position to be
the right operand of '++'.
 
J

James Kuyper

Francis said:
yes but initialy I thought these two operators didn't have the same
precedence.

What would happen if they didn't have the same precedence ?

*++p would still be parsed as *(++p), and ++*p would still be parsed as
++(*p). Precedence can never come into play when both operators are on
the same side of 'p'.
 
R

Richard Tobin

Precedence indicates how operators bind. It cannot rearrange
operators and change their operands. For each of the two expressions:

What is the operand of the ++ operator?

What is the operand of the * operator?
[/QUOTE]
yes but initialy I thought these two operators didn't have the same
precedence.

What would happen if they didn't have the same precedence ?

Think of it like this: precedence just provides automatic insertion of
brackets. For example, the relative precedence of + and * means that
a+b*c is equivalent to a+(b*c).

Now there's no way of inserting brackets in *++p to make the * go
with p, or in ++*p to make the ++ go with p, so precedence is irrelevant.

-- Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top