The Wikipedia article on C and C++ operators

R

Robbie Hatley

Victor Bazarov said:
The ternary expression falls under "conditional-expression" part of the
grammar. The second part of it is "expression" and the third part of it
is "assignment-expression". So, we can write

c = a > b ? a : b; /* assign larger of {a,b} to c */

which makes ternary higher in precedence than assingment, at the same
time if we write

c = a > b ? a : b = a;

, the 'c' isn't only assigned the 'a' value, 'b' is also changed if it
is larger.

Try to position this correctly in the precedence table.

I tried compiling that in a C program, and gcc gives me
"error: invalid lvalue in assignment". But oddly, when
I change the file-name suffix from "c" to "cpp" and compile
with gpp instead of gcc, it compiles without error.

So apparently there's a major difference between how C vs. C++
handle that line of code.

I wonder if the semantics are guaranteed even if the syntax
makes it through the compiler? Perhaps it's another case like:

a = i++;


--
Cheers,
Robbie Hatley
Tustin, CA, USA
lone wolf intj at pac bell dot net
(put "[usenet]" in subject to bypass spam filter)
home dot pac bell dot net slant earnur slant
 
E

Eric Sosman

Andrey Tarasevich wrote On 07/28/06 14:49,:
That's where some differences between C and C++ come into play.

In C, from a formal point of view (as dictated by the language grammar),
precedence of postfix increment/decrement _is_ higher than that of prefix
increment/decrement. But the need to compare the two might only arise in
expressions like

++v--; /* it is '++(v--)', not (++v)-- */

which is well-formed, but produces undefined behavior.

It produces a compiler diagnostic. It is syntactically
well-formed, but violates a semantic constraint: the operand
of ++ is not an lvalue. ++42 is syntactically well-formed
and violates the same constrant.

(Of course, the compiler is permitted to accept the
program and generate code in addition to emitting the
required diagnostic; the effect of executing any such
program would, as you say, be undefined.)
 
A

Andrey Tarasevich

Eric said:
It produces a compiler diagnostic. It is syntactically
well-formed, but violates a semantic constraint: the operand
of ++ is not an lvalue. ++42 is syntactically well-formed
and violates the same constrant.
...

You are right. I missed that
 
F

Frederick Gotham

Andrey Tarasevich posted:
++v--; /* it is '++(v--)', not (++v)-- */

which is well-formed, but produces undefined behavior.


<OFF TOPIC>

This is more of a nitpick than anything else, but if we're talking about C++,
then it's possible for such a statement to be pefectly OK, depending on the
definitions of operator++ and operator--(int).

</OFF TOPIC>
 
A

Andrey Tarasevich

Frederick said:
Andrey Tarasevich posted:



<OFF TOPIC>

This is more of a nitpick than anything else, but if we're talking about C++,
then it's possible for such a statement to be pefectly OK, depending on the
definitions of operator++ and operator--(int).

</OFF TOPIC>

But that's exactly what I said in the next paragraph of the message you were
replying to.
 
D

Default User

Richard said:
Victor Bazarov said:
Robert Gamble wrote:
Victor Bazarov wrote:
[..]

You seem to have a fundamental misunderstanding of the effective
precedence of operators in C. [..]

You cross-posted this to both C and C++ newsgroups.

Well, the OP did, without setting a followup.

I have no idea what a followup is or how to set one !


That's fine, because you should not have set one.



Brian
 
R

Richard Heathfield

Victor Bazarov said:
Richard said:
Victor Bazarov said:
Robert Gamble wrote:
Victor Bazarov wrote:
[..]

You seem to have a fundamental misunderstanding of the effective
precedence of operators in C. [..]

You cross-posted this to both C and C++ newsgroups.

Well, the OP did, without setting a followup.

Why would follow-up be needed?

Cross-posting is generally a bad idea (although it's a better idea than
multi-posting, of course). When it must be done, 'twere best 'twere done
with a follow-up to a particular group.
REALLY? What makes you think that? Could it be this part of the
orginal post that gives it away:

^^^^^^^^^^^^^^^^^^^^^^

Oops. Yes, I did indeed miss that part of it. I'm not sure it was necessary
to yell, though.

<snip>
 
R

Richard Heathfield

Victor Bazarov said:
So why did you mix C++ into it? Anyway, the one on the Wikipedia
page you asked about seems to be fine.

For now[1]. Give it time.


[1] Maybe. I didn't look. I didn't see the point.
 
D

Default User

Richard Heathfield wrote:

Cross-posting is generally a bad idea (although it's a better idea
than multi-posting, of course). When it must be done, 'twere best
'twere done with a follow-up to a particular group.


NO NO NO!


It's very rude to cross-post and set follow-ups. What are people in the
other groups supposed to do, subscribe to some other group to continue
the thread? If the answers don't belong in all the groups, the original
post didn't either. The only legitimate use of follow-up-to is to
redirect an off-topic post to another group. It should never be a
deliberate method by the original poster.



Brian
 
R

Robert Gamble

Victor said:
Robert said:
[..]
Since the OP was asking about C

The OP was asking about *both*. The Wikipedia article is about *both*.

Well, sort of. The OP was looking for a C precedence table and asked
if the one that appeared on a page about C and C++ and contained C++
operators would work for C. The OP didn't seem interested in how
things work in C++, just if the table provided was compatible with C,
given that context I think my interpreation of your example (which
didn't specify C or C++) was reasonable.
[..] The third part of
the conditional expression in C++ is "assignment expression", in C it
is "conditional expression" which is why this isn't valid in C.

The second part of the ternary variant of 'conditional-expression' in
C is 'expression'. So in C I should be albe to write

b < a ? b , a : a , b;

Yes, it would be the same thing as:

(b < a ? (b , a) : a) , b;
Which can be quite confusing even in C, don't you think?

Not nearly as much so as the C++ example you provided which I think is
quite unintuitive.
How does it
fit into lower precedence of the comma operator?

The conditional operator is special in that it is the only ternary
operator in the language. The ? and : symbols delimit the enclosing
expression making "a ? b : c" equivalent to "a ? (b) : c". Once one
realizes this it makes sense that an expression with lower precedence
operators are handled the way they are, there is not precendence
inconsistency.

Robert Gamble
 
R

Richard Heathfield

Default User said:
Richard Heathfield wrote:



NO NO NO!

Or yes.
It's very rude to cross-post and set follow-ups.

I beg your leave to differ. Cross-posting should be avoided if possible. If
it cannot be avoided, it should at least be minimised. Setting a follow-up
contributes to this goal.

What are people in the
other groups supposed to do, subscribe to some other group to continue
the thread?

Yes, if they care enough. No, if they don't.

<snip>
 
D

Default User

Richard said:
Default User said:


Or yes.


I beg your leave to differ. Cross-posting should be avoided if
possible. If it cannot be avoided, it should at least be minimised.
Setting a follow-up contributes to this goal.

There are no circumstances where it can't be avoided. Any use is
completely discretionary. You can't convince me that it is anything
other than extremely rude to say, "Here's a cool topic, but you can't
see the answers here! Come on over to xxx.yyy.zzz. I don't care that
you don't subscribe!"
Yes, if they care enough. No, if they don't.

I just cannot agree with this. If the reply doesn't belong, it should
not have appeared in the first place. If the post was topical, then so
are the replies.

To ask people to move to another group is rude and thoughtless in my
opinion. I will say so emphatically every time I see someone suggest it.



Brian
 
R

Richard Heathfield

Default User said:

To ask people to move to another group is rude and thoughtless in my
opinion. I will say so emphatically every time I see someone suggest it.

I'm not sure where this matter ought to be discussed, but it's clearly no
longer topical in clc or clc++.
 
D

Default User

Richard said:
Default User said:



I'm not sure where this matter ought to be discussed, but it's
clearly no longer topical in clc or clc++.

You don't consider it to be metatopical? We are discussing how to post
in the relevant newsgroups. I have no desire to argue with you about
it, you know my feelings on the subject.




Brian
 
O

Old Wolf

Victor said:
In C++ postfix has higher precedence than prefix. The table seems fine
there. I am certain that in C it is the same.

Can you give an example of that? I think both versions of ++ should
be in the lower category, although I can't think of any examples where
the behaviour is defined, and there would be a difference.
 
V

Victor Bazarov

Old said:
Can you give an example of that?

An example of what?

int main() {
int a = 42;
++a++; /* shouldn't compile: prefix applied to an r-value */
}

Or the idiomatic

*ptr++

(first increment, then dereference using the old value).
I think both versions of ++ should
be in the lower category, although I can't think of any examples where
the behaviour is defined, and there would be a difference.

In lower category? Meaning what? How would you deal with grouping of the
operations? Left-to-right first? Right-to-left first? How would you
deal with this:

int arr[10] = {1,2,3}, *pa = arr, b = pa++[0];

? The higher-precedence indexing applied to the result of the lower-
precedence increment? Notice that all higher precedence operators are
postfix (increment/decrement, function call, subscript, member access
for objects, member access for pointers) and all lower precedence
operators are prefix - increment/decrement, unary plus/minus, not and
bitwise zero complement, type cast, dereference and address-of.

V
 
F

Frederick Gotham

Default User posted:
You can't convince me that it is anything other than extremely rude to
say, "Here's a cool topic, but you can't see the answers here! Come on
over to xxx.yyy.zzz. I don't care that you don't subscribe!"


Maybe we should abolish all of the newsgroups, and everyone should just post
to alt.talk.
 
O

Old Wolf

Victor said:
An example of what?

An example showing where putting postfix ++ in the lower category
would give a different way of parsing than if it's in the higher
category.
int main() {
int a = 42;
++a++; /* shouldn't compile: prefix applied to an r-value */
}

An example that compiles and has defined behaviour.
Or the idiomatic

*ptr++

(first increment, then dereference using the old value).

You're confusing precedence with order of evaluation
(either that or I miss your point). In that example,
postfix ++ could be in the lower category (ie. the same
category as unary *), because that category is
right-associative, so it is *(ptr++) .
In lower category? Meaning what?

In the category of prefix ++, in the table which is the topic
of this thread.
How would you deal with grouping of the
operations? Left-to-right first? Right-to-left first?

Right to left, as stated in that table.
How would you deal with this:

int arr[10] = {1,2,3}, *pa = arr, b = pa++[0];

The only possible ways of parsing that are:
... ((b = pa)++)[0]
and
... b = ((pa++)[0])
and
... (b = (pa++))[0]

and the precedence of ++ is higher than that of
=, so the first is out; and the precedence of [] is higher
than that of =, so the last is out. The relative precedence
of [] and ++ is not involved in this one.
? The higher-precedence indexing applied to the result of the lower-
precedence increment?

The way it is written, there is not a precedence decision involved.
 

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

No members online now.

Forum statistics

Threads
473,796
Messages
2,569,645
Members
45,371
Latest member
TroyHursey

Latest Threads

Top