Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

*x++ diff. from (*x)++ ???

1,361 views
Skip to first unread message

John Wu

unread,
Jun 6, 1998, 3:00:00 AM6/6/98
to

Hi...,

I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
where (*x)++ means increment the value pointed by x. But I don't know what
*x++ means.
In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
example which pointed that " *xPos++" means dereference, then increment ".
I tried as what mentioned on the book, but the result is not what it
supposed to be.
Any explanation would be greatly appreciated.


TIA
John


--
comp.lang.c.moderated - cl...@plethora.net

Kaz Kylheku

unread,
Jun 6, 1998, 3:00:00 AM6/6/98
to

In article <clcm-1998...@plethora.net>,

John Wu <joh...@slsbearing.com.sg> wrote:
>Hi...,
>
>I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
>where (*x)++ means increment the value pointed by x. But I don't know what
>*x++ means.

*x++ means dereference the previous value of x, and store the new value x + 1
into x.

>In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an

Hahaha.

>example which pointed that " *xPos++" means dereference, then increment ".

No it doesn't. It means dereference the old value and increment Pos.
There is no chronological order in which the two happen, they are
independent operations, so it's wrong to use the word ``then''.

TankCPU

unread,
Jun 6, 1998, 3:00:00 AM6/6/98
to

There must be some chronological order because a common statement such as

*x++ = *y++;

would give inconsistent or platform specific results. As you have described
it, the statement above might mean

*x = *y; x++; y++;

or

x++; y++; *x = *y;

or (doubtfully)
x++; *x = *y; y++;
y++; *x = *y; x++;

cla...@mci2000.com

Gary Yngve

unread,
Jun 6, 1998, 3:00:00 AM6/6/98
to

TankCPU <tan...@aol.com> wrote:
: There must be some chronological order because a common statement such as

: *x++ = *y++;

As far as I know, this is well-defined. It should be equivalent to


*x = *y; x++; y++;

But something like a[x]=x++ is implementation-dependent.

--
Dijkstra for President! | Gary Yngve
| ga...@cc.gatech.edu


firewind

unread,
Jun 6, 1998, 3:00:00 AM6/6/98
to

On 6 Jun 1998, TankCPU wrote:

> There must be some chronological order

Chronological order?

> because a common statement such as
>
> *x++ = *y++;
>

> would give inconsistent or platform specific results.

It always has the same results; the value of '*y' is stored in '*x' and 'x'
and 'y' are both incremented at some point prior to the next sequence point.

> As you have described it, the statement above might mean

It means '*x++ = *y++'. No more, no less.

> *x = *y; x++; y++;

No. This sequence of statements is not equivilant, since it contains three
sequence points instead of one. Functionally, however, I suppose it is
allowable.

> x++; y++; *x = *y;

Um, no. Did you somehow miss that we were using the -postfix- operators
here, which indicate that the -unincremented- value is the result of the
expression?

--
(initiator of the campaign for grumpiness where grumpiness is due in c.l.c)

Attempting to write in a hybrid which can be compiled by either a C compiler
or a C++ compiler produces a compromise language which combines the drawbacks
of both with the advantages of neither.
-- John Winters <jo...@polo.demon.co.uk> in comp.lang.c


firewind

unread,
Jun 6, 1998, 3:00:00 AM6/6/98
to

On 6 Jun 1998, Gary Yngve wrote:

> But something like a[x]=x++ is implementation-dependent.

No. It is undefined behaviour, and will cause demons to launch themselves
out of your nose at an astonishing speed.

Kaz Kylheku

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

In article <199806062226...@ladder01.news.aol.com>,
TankCPU <tan...@aol.com> wrote:
>There must be some chronological order because a common statement such as
>
>*x++ = *y++;
>
>would give inconsistent or platform specific results. As you have described

>it, the statement above might mean
>
>*x = *y; x++; y++;
>
>or

>
>x++; y++; *x = *y;
>
>or (doubtfully)
>x++; *x = *y; y++;
>y++; *x = *y; x++;

It doesn't mean any of these. It means that a value is copied from
the object designated by the prior value of pointer y to the
object designated by the prior value of pointer x. Somewhere in the same
evaluation phase, x and y are updated with the new values x + 1
and y + 1 respectively.

It doesn't matter when this update happens relative to the assignment
operation, because the assignment uses the prior values of the pointers.

A compiler could emit code which caches the prior values, performs both
increments and then does the assignment using the prior values.

Kaz Kylheku

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

In article <6lcgo0$l5r$1...@news-int.gatech.edu>,

Gary Yngve <ga...@angband.org> wrote:
>TankCPU <tan...@aol.com> wrote:
>: There must be some chronological order because a common statement such as
>
>: *x++ = *y++;
>
>As far as I know, this is well-defined. It should be equivalent to
>*x = *y; x++; y++;

Unless x and y are volatile objects, in which case the two forms
are not equivalent.

>But something like a[x]=x++ is implementation-dependent.

You misspelled undefined. :)

Lawrence Kirby

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

In article <199806062226...@ladder01.news.aol.com>
tan...@aol.com "TankCPU" writes:

>There must be some chronological order because a common statement such as
>
>*x++ = *y++;

No, the increments can happen at any point between the enclosing sequence
points. However the value of an expression like n++ is defined independently
of when the side-effect (of writing a new value to n) occurs. n++ is
defined to forwards the original value of n to any enclising expression and
++n is defined to return the original value plus 1.

>would give inconsistent or platform specific results. As you have described
>it, the statement above might mean
>

>*x = *y; x++; y++;

That has the same effect in this case

>or
>
>x++; y++; *x = *y;

That doesn't. Another way of implementing this that would be correct is:

tmp1 = x; tmp2 = y; x++; y++; *tmp1 = *tmp2;

You'll see here that x and y get incremented before the assignment takes
place.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------


Ben Pfaff

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
where (*x)++ means increment the value pointed by x. But I don't know what
*x++ means.

int a[] = {10, 20, 30};
int *x = a;

printf ("%d", *x++); /* Prints 10, *x is now 20. */
printf ("%d", (*x)++); /* Prints 20, *x is now 21. */
--
comp.lang.c.moderated - cl...@plethora.net

Jimi Lee

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

>I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
>where (*x)++ means increment the value pointed by x. But I don't know what
>*x++ means.


In Visual C++ 5.0, *x++ means (*x)++. And I Test these for correctness.

See next code:
printf("%d",*x++);

Initialy, *x=1 and *(x+1)=10.
After do that code, 1 is printed and *x increased. *(x)=2 and *(x+1)=10;

if code is "printf("%d",*(x++));", 1 printed and *(x)=10. *(x-1)=1;

When "printf("%d",++(*x));" ??
2 is printed and *(x)=2, (x+1)=10.

Bonus...
When "printf("%d",*(++x));" ??
10 is printed and *(x)=10, (x-1)=1.

I hope to your help.... ^.^;

--
comp.lang.c.moderated - cl...@plethora.net

Craig Franck

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

John Wu <joh...@slsbearing.com.sg> wrote:
>Hi...,
>
>I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
>where (*x)++ means increment the value pointed by x. But I don't know what
>*x++ means.

*x++ is like array subscripting. If x is pointing to an array
element, you can think of *x++ as meaning a[i++]. You are
incrementing the pointer, not what is pointed to. *x++ means
*(x++). The question that needs to be answered in figuring
this out is whether the ++ aplies to x or *x. There is a
natural binding that takes place, and using parentheses can
force it to be one or the other. The ++ binds to the x; so
the pointer gets incremented. As you learned, the parentheses
in (*x)++ force the ++ to apply to *x.

>In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an

>example which pointed that " *xPos++" means dereference, then increment ".

>I tried as what mentioned on the book, but the result is not what it
>supposed to be.

That's ambiguous because you need to distinguish between whether
it's the pointer that's incremented or what's pointed to. Below
is a chart from "C Programming: A Modern Approach". In it, *p
refers to what's pointed to and p refers to the pointer itself.

Expression Meaning
*p++ or *(p++) Value of expression is *p before increment; increment p later
(*p)++ Value of expression is *p before increment; increment *p later
*++p or *(++p) Increment p first; value of expression is *p after increment
++*p or ++(*p) Increment *p first; value of expression is *p after increment

--
Craig
clfr...@worldnet.att.net
Manchester, NH
If you have enough spiritual power to levitate a car, what
difference does it make what religion you call yourself?
-- "Stella"
--
comp.lang.c.moderated - cl...@plethora.net

John Kugelman

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

John Wu wrote:
>
> Hi...,
>
> I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
> where (*x)++ means increment the value pointed by x. But I don't know what
> *x++ means.

With parentheses it increments the value pointed to. Without, it
increments the pointer. Either way, the value of the expression is
"*x".

To illustrate:

int main (void)
{
int i [3] = { 0 }, *p, x;

p = i;

/* Now x == ?, p == &i[0], i == {0,0,0} */

x = (*p)++;
/* Now x == 0, p == &i[0], i == {1,0,0} */

x = *p++;
/* Now x == 1, p == &i[1], i == {1,0,0} */

return 0;
}

--
John Kugelman. kuge...@mnsinc.com

I believe we can change anything.
I believe in my dream.
- Joe Satriani
--
comp.lang.c.moderated - cl...@plethora.net

Cathy

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

In article <clcm-1998...@plethora.net>, John Wu
<joh...@slsbearing.com.sg> wrote:

> Hi...,
>
> I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
> where (*x)++ means increment the value pointed by x. But I don't know what
> *x++ means.

> In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
> example which pointed that " *xPos++" means dereference, then increment ".
> I tried as what mentioned on the book, but the result is not what it
> supposed to be.

> Any explanation would be greatly appreciated.

I *believe* that *x++ means the same as the following *(x++). What this
would do is to advance the *pointer* x one memory unit forward. This is
useful for advancing a pointer through an array, but can cause large
numbers of headaches and problems if that's not what you meant to do.

--John Christensen
--
comp.lang.c.moderated - cl...@plethora.net

Bjørn Harald Rapp

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

John Wu wrote in message ...


>Hi...,
>
>I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
>where (*x)++ means increment the value pointed by x. But I don't know what
>*x++ means.
>In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
>example which pointed that " *xPos++" means dereference, then increment
".
>I tried as what mentioned on the book, but the result is not what it
>supposed to be.
>Any explanation would be greatly appreciated.
>
>

>TIA
>John

Assume that x points to an integer that contains the value 1. Contrary to
what you might think, the statement *x++ first increments the pointer x
itself, and then obtains the value at the new location. If your intention
is to increment what is pointed to by a pointer, you correctly have to use
the form (*x)++.

Best regards

Bjørn-Harald Rapp

b.r...@st.telia.no

--
comp.lang.c.moderated - cl...@plethora.net

John Kugelman

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

TankCPU wrote:
>
> There must be some chronological order because a common statement such as
>
> *x++ = *y++;
>
> would give inconsistent or platform specific results. As you have described
> it, the statement above might mean
>
> *x = *y; x++; y++;

That is correct (if x!=y).

> or
>
> x++; y++; *x = *y;

This is not. The prefix increment operator would produce this behavior.

>
> or (doubtfully)
> x++; *x = *y; y++;
> y++; *x = *y; x++;

Kaz's point, I presume, is that whether or not the pointers are actually
dereferenced before the increments is unspecified. A compiler is free
to rewrite the code as this:

type *tmpx, *tmpy;
tmpx = x; tmpy = y;
x++; y++; *tmpx = *tmpy;

or

type tmpy;
tmpy = *y; y++;
*x = tmpy; x++;

When the deferences and increments occur with respect to each other
cannot be determined, as long as the behavior is correct, since they are
independent operations.

You are also right, though, but of a different point. The compiler must
behave "as if" the increments take place after the dereferences. Kaz
was just being more specific.

Gary Yngve

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

Kaz Kylheku <k...@cafe.net> wrote:
: In article <6lcgo0$l5r$1...@news-int.gatech.edu>,
: Gary Yngve <ga...@angband.org> wrote:

:>TankCPU <tan...@aol.com> wrote:
:>: There must be some chronological order because a common statement such as
:>
:>: *x++ = *y++;
:>
:>As far as I know, this is well-defined. It should be equivalent to
:>*x = *y; x++; y++;

: Unless x and y are volatile objects, in which case the two forms
: are not equivalent.

Good point. Are there any other real uses for volatile objects other than
flags for signal handlers?

Jack Klein

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

On 7 Jun 1998 06:12:54 GMT, Gary Yngve <ga...@angband.org> wrote:

>Kaz Kylheku <k...@cafe.net> wrote:
>: In article <6lcgo0$l5r$1...@news-int.gatech.edu>,
>: Gary Yngve <ga...@angband.org> wrote:
>:>TankCPU <tan...@aol.com> wrote:
>:>: There must be some chronological order because a common statement such as
>:>
>:>: *x++ = *y++;
>:>
>:>As far as I know, this is well-defined. It should be equivalent to
>:>*x = *y; x++; y++;
>
>: Unless x and y are volatile objects, in which case the two forms
>: are not equivalent.
>
>Good point. Are there any other real uses for volatile objects other than
>flags for signal handlers?
>

<Jack>

There are quite a few uses for the volatile keyword besides signal
handlers. The most obvious fall into two categories: memory-mapped
hardware (the received data register in your UART can certainly change
without your compiler's knowledge), and multitasking.

Memory mapped hardware is outside the scope of standard C (although
tolerated in the sense that it is legal to cast an "arbitrary" integer
value to a pointer, with the result being implementation-defined).

Multitasking (other than signal handling) is truly outside the
standard, but it certainly does exist.

</Jack>


Lawrence Kirby

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

In article <6ldbp5$5...@espresso.cafe.net> k...@cafe.net "Kaz Kylheku" writes:

...

>In a strictly conforming C program, the only use for volatile is
>for declaring an object of type volatile sig_atomic_t which can be
>safely modified by a signal handler.

It also has a standard use in functions that call setjmp(): automatic
variables become indeterminate if they were modified between the setjmp()
and longjmp() call back to the function, unless they are defined as
volatile.

firewind

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

On Sun, 7 Jun 1998 gail...@best.com wrote:

> JAVA CLASS INSTRUCTOR NEEDED

RAT HAIRSPRAY RECOMMENDATIONS NEEDED

--
(initiator of the campaign for grumpiness where grumpiness is due in c.l.c)

news:news.announce.newusers


jim.h...@leitch.com

unread,
Jun 8, 1998, 3:00:00 AM6/8/98
to

In article <clcm-1998...@plethora.net>,

"Bjørn Harald Rapp" <b.r...@st.telia.no> wrote:
>
>
> John Wu wrote in message ...
> >Hi...,
> >
> >I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
> >where (*x)++ means increment the value pointed by x. But I don't know what
> >*x++ means.
> >In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
> >example which pointed that " *xPos++" means dereference, then increment
> ".
> >I tried as what mentioned on the book, but the result is not what it
> >supposed to be.
> >Any explanation would be greatly appreciated.
> >
> >
> >TIA
> >John
>
> Assume that x points to an integer that contains the value 1. Contrary to
> what you might think, the statement *x++ first increments the pointer x
> itself, and then obtains the value at the new location.
No. The *original* value of x is used. You are confusing pre-increment and
post-increment. For example:
void aFunc()
{
int arr[2];
int *x=arr;
int y;

arr[0]=0;
arr[1]=1;
y=*x++;
printf("*x: %d; y: %d\n", *x, y);
}

The output will be:
x: 1; y: 0

> If your intention
> is to increment what is pointed to by a pointer, you correctly have to use
> the form (*x)++.

Correct.


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading

Joe Maun

unread,
Jun 10, 1998, 3:00:00 AM6/10/98
to

Bjørn Harald Rapp wrote:
>
> John Wu wrote in message ...
> >Hi...,
> >
> >I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
> >where (*x)++ means increment the value pointed by x. But I don't know what
> >*x++ means.
> >In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
> >example which pointed that " *xPos++" means dereference, then increment
> ".
> >I tried as what mentioned on the book, but the result is not what it
> >supposed to be.
> >Any explanation would be greatly appreciated.
> >
> >
> >TIA
> >John
>
> Assume that x points to an integer that contains the value 1. Contrary to
> what you might think, the statement *x++ first increments the pointer x
> itself, and then obtains the value at the new location. If your intention

It abtains the value at the _old_ location. what you described happens
when you use pre-increment: *++x;

> is to increment what is pointed to by a pointer, you correctly have to use
> the form (*x)++.
>

Joe
--
comp.lang.c.moderated - cl...@plethora.net

Dave Hansen

unread,
Jun 10, 1998, 3:00:00 AM6/10/98
to

On Sun, 07 Jun 1998 02:19:51 GMT, "Jimi Lee" <le...@adam.kaist.ac.kr>
wrote:

>>I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
>>where (*x)++ means increment the value pointed by x. But I don't know what
>>*x++ means.
>
>

>In Visual C++ 5.0, *x++ means (*x)++. And I Test these for correctness.
>

Really? Let's check it out...

---
D:\DAVE>type autoinc.c
#include <stdio.h>

int main(void)
{
int a1[] = {10, 20, 30};
int a2[] = {10, 20, 30};
int *x1=a1, *x2=a2;
int y1, y2;

y1 = *x1++;
y2 = (*x2)++;

printf("a1 is %d, %d, %d, y1 is %d, and x1 points to %d\n",
a1[0],a1[1],a1[2], y1, *x1);

printf("a2 is %d, %d, %d, y2 is %d, and x2 points to %d\n",
a2[0],a2[1],a2[2], y2, *x2);

return 0;
}

D:\DAVE>cl autoinc.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 11.00.7022 for
80x86
Copyright (C) Microsoft Corp 1984-1997. All rights reserved.

autoinc.c
Microsoft (R) 32-Bit Incremental Linker Version 5.00.7022
Copyright (C) Microsoft Corp 1992-1997. All rights reserved.

/out:autoinc.exe
autoinc.obj

D:\DAVE>autoinc
a1 is 10, 20, 30, y1 is 10, and x1 points to 20
a2 is 11, 20, 30, y2 is 10, and x2 points to 11

D:\DAVE>
---

Well, not quite the same thing. At least not with _my_ copy of
VC/C++ 5.0...

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.
--
comp.lang.c.moderated - cl...@plethora.net

glam...@my-dejanews.com

unread,
Jun 10, 1998, 3:00:00 AM6/10/98
to

In article <clcm-1998...@plethora.net>,
John Wu <joh...@slsbearing.com.sg> wrote:
>
> Hi...,
>
> I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
> where (*x)++ means increment the value pointed by x. But I don't know what
> *x++ means.
> In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
> example which pointed that " *xPos++" means dereference, then increment ".
> I tried as what mentioned on the book, but the result is not what it
> supposed to be.
> Any explanation would be greatly appreciated.
>
> TIA

I believe that one would increment the address pointed to by x by one and the
other would increment the value stored at the address x by one but off the top
of my head, i do not know which is which.

Hope it helps

mathew

> John
>
> --
> comp.lang.c.moderated - cl...@plethora.net
>

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading

--
comp.lang.c.moderated - cl...@plethora.net

har...@hotmail.com

unread,
Jun 10, 1998, 3:00:00 AM6/10/98
to

On Sat, 06 Jun 1998 15:55:13 GMT, John Wu <joh...@slsbearing.com.sg>
wrote:

>Hi...,
>
>I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
>where (*x)++ means increment the value pointed by x. But I don't know what
>*x++ means.
>In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
>example which pointed that " *xPos++" means dereference, then increment ".
>I tried as what mentioned on the book, but the result is not what it
>supposed to be.
>Any explanation would be greatly appreciated.
>
>

You can find that answer in K&R, read it.
It means that you increment a pointer.
--
comp.lang.c.moderated - cl...@plethora.net

Paul D. Eccles

unread,
Jun 12, 1998, 3:00:00 AM6/12/98
to

Bjørn Harald Rapp wrote:
>
> John Wu wrote in message ...
> >Hi...,
> >
> >I am new to C/C++ and I found that " *x++ " is different from " (*x)++ ",
> >where (*x)++ means increment the value pointed by x. But I don't know what
> >*x++ means.
> >In "Teach Yourself Borland C++ Builder 3 in 21 Days" (p.83) there is an
> >example which pointed that " *xPos++" means dereference, then increment
> ".
> >I tried as what mentioned on the book, but the result is not what it
> >supposed to be.
> >Any explanation would be greatly appreciated.
> >
> >
> >TIA
> >John
>
> Assume that x points to an integer that contains the value 1. Contrary to
> what you might think, the statement *x++ first increments the pointer x
> itself, and then obtains the value at the new location. If your intention
> is to increment what is pointed to by a pointer, you correctly have to use
> the form (*x)++.
>
> Best regards
>
> Bjørn-Harald Rapp
>
> b.r...@st.telia.no

No it firsts obtains the value at the location of x then increments the
pointer x. ++*x does what you describe.

Paul Eccles
--
comp.lang.c.moderated - cl...@plethora.net

Vallström

unread,
Jun 15, 1998, 3:00:00 AM6/15/98
to

>> Assume that x points to an integer that contains the value 1. Contrary to
>> what you might think, the statement *x++ first increments the pointer x
>> itself, and then obtains the value at the new location. If your
intention
>> is to increment what is pointed to by a pointer, you correctly have to
use
>> the form (*x)++.
>>
>> Best regards
>>
>> Bjørn-Harald Rapp
>>
>> b.r...@st.telia.no
>
>No it firsts obtains the value at the location of x then increments the
>pointer x. ++*x does what you describe.
>
>Paul Eccles
>--
>comp.lang.c.moderated - cl...@plethora.net

No *++x does what Bjørn-Harald Rapp described...:-) (++*x increments
what x points to, before its use.)

Daniel Vallström


--
comp.lang.c.moderated - cl...@plethora.net

BHamm2

unread,
Jun 17, 1998, 3:00:00 AM6/17/98
to

Ok, I'm kind of new to C (5 years of self taught, playing around) but I don't
understand why so many of you folks ask these kind of ?s when you can just
write some simple code and check it with a few printf( )'s. Then you'll know
the answer.
Bob Hammond

John Christensen

unread,
Jun 17, 1998, 3:00:00 AM6/17/98
to

In article <199806170410...@ladder03.news.aol.com>,
bha...@aol.com (BHamm2) wrote:

Actually, in this case that wouldn't work very well. That would tell you
how your *compiler* handles *x++. Unfortunately, I don't believe the
behavior of that is defined by the C standard. Why? because * and ++ have
the same precendence.

--John Christensen

Will Rose

unread,
Jun 17, 1998, 3:00:00 AM6/17/98
to

BHamm2 (bha...@aol.com) wrote:
: Ok, I'm kind of new to C (5 years of self taught, playing around) but I don't
: understand why so many of you folks ask these kind of ?s when you can just
: write some simple code and check it with a few printf( )'s. Then you'll know
: the answer.

You'll know _an_ answer. It'll be correct for that revision of that
compiler on that machine, but that's a pretty limited sort of correctness.
If you need compiler-specific information, then the best place to ask is
in a group which deals with that specific compiler. This group generally
discusses standard C, with the idea that code which is written as closely
to the standard as possible will be reliable and portable, even to machines
and compilers not known to the user.


Will
c...@crash.cts.com


John Kugelman

unread,
Jun 17, 1998, 3:00:00 AM6/17/98
to

John Christensen wrote:
>
> In article <199806170410...@ladder03.news.aol.com>,
> bha...@aol.com (BHamm2) wrote:
>
> > Ok, I'm kind of new to C (5 years of self taught, playing around) but I don't
> > understand why so many of you folks ask these kind of ?s when you can just
> > write some simple code and check it with a few printf( )'s. Then you'll know
> > the answer.
> > Bob Hammond
>
> Actually, in this case that wouldn't work very well. That would tell you
> how your *compiler* handles *x++. Unfortunately, I don't believe the
> behavior of that is defined by the C standard. Why? because * and ++ have
> the same precendence.

No, the behavior is well-defined by the standard. The standard doesn't
define precedence or associativity, but they are two concepts that you
can draw out of it. The unary operators are right associative, which
means that x binds to the ++ first, i.e. *(x++)

This has already been explained in this thread in much detail.

However, your point was right for a different reason. While testing a
program on your compiler is a good way to see if something works, it
shouldn't be the end of your testing. Something that works on one
compiler might bomb on the next, and this is often the case for many
things. However, if your compiler is one that bombs on a certain
construct, then it's fairly safe to say (barring compiler bugs) that
that code is wrong.

John Christensen

unread,
Jun 17, 1998, 3:00:00 AM6/17/98
to

In article <clcm-1998...@plethora.net>, jim.h...@leitch.com wrote:

> In article <clcm-1998...@plethora.net>,

> *++x does what Bjørn-Harald Rapp described, but that is not what he wrote - he
> wrote *x++ (which does what Paul Eccles describes).
>
> To summarize, we have now talked about three different combinations (not
> including parentheses):
> *x++;
> *++x;
> ++*x;
>
> The behavior of each of these is (see FOOTNOTE):
> *x++: Get the value at x, then increment x
> *++x: Increment x, then get what it points to
> ++*x: Increment the value pointed to by x (x is not changed)
>
To tell the truth, I think there may be another, less-happy answer for
this one. After checking The ANSI C Programming Language(Kerningham &
Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
this? Because the * and the ++ operators both have the exact save
precedence according to the table on page 53 of that book. Therefore I
believe the answer to this question to be that C does not define this
behavior, and that the behavior will depend on compiler implementation.
Perhaps we could find out how the common compilers handle this?

Yes, I know this completely contradicts the answer I wrote about a week
ago. I actually looked at my C book. Also sorry if I'm missing some hugely
obvious point.

John Christensen

unread,
Jun 18, 1998, 3:00:00 AM6/18/98
to

In article <6m9a3h$9...@espresso.cafe.net>, k...@cafe.net wrote:

> In article <clcm-1998...@plethora.net>,


> John Christensen <jc6...@acs.brockport.edu> wrote:
> >To tell the truth, I think there may be another, less-happy answer for
> >this one. After checking The ANSI C Programming Language(Kerningham &
> >Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> >this? Because the * and the ++ operators both have the exact save
> >precedence according to the table on page 53 of that book.
>

> The venerable table on page 53 also has a column labelled ``associativity''.
> Operators on the same level of precedence are disambiguated according
> to left or right associativity. For example, the additive operators
> + and - have left associativity, so that a + b - c + d means
> ((a + b) - c) + d .
>
> There are two flavors of the ++ operator. The unary expression one
> appears to the left of an expression. It is that operator which has
> equal precedence to the dereference * operator. The postfix form
> which appears to the right of an expression has a higher precedence.
> Thus
>
> *x++
>
> really means
>
> *(x++)
>
> according to precedence---associativity doesn't even enter into it. REad the
> table more carefully.
>
> The unary operators are right associative, so that
>
> *++x
>
> can only possibly mean
>
> *(++x)
>
> and not the meaningless combination
>
> (*++)x
>
>

Yes, it appears when I made that post I made it without a leg to stand on.
Apologies for goofing on that one:>

--John Christensen

TechThug

unread,
Jun 18, 1998, 3:00:00 AM6/18/98
to

On 18 Jun 1998 02:48:57 GMT, jc6...@acs.brockport.edu (John
Christensen) wrote:


>Yes, it appears when I made that post I made it without a leg to stand on.
>Apologies for goofing on that one:>

WHAT????

That goes against any usenet rules... NEVER ADMIT YOUR WRONG!!

The police will be calling on you shortly ;)
Rob Humphris
Don't Ask for my opinion on anything, you might just get it

Lawrence Kirby

unread,
Jun 18, 1998, 3:00:00 AM6/18/98
to

In article <6m9a3h$9...@espresso.cafe.net> k...@cafe.net "Kaz Kylheku" writes:

...

>Even if what you were saying were true, you would be wrong in believing
>that what is written in the K&R2 book defines the language. What is
>defined or not can only be judged by the actual standard document.
>
>There is in fact a flaw in the book, because the ++ and -- operators
>fail to appear in the top row of the table.

There's no reason why they should.

>If you look in the grammar on page 238, you will see:
>
> postfix-expression:
> primary-expression
> postfix-expression [ expression ]
> postfix-expresion ( argument-expression-list_opt )
> postfix-expression . identifier
> postfix-expression -> identifier
> postfix-expression ++
> postfix-expression --
>
>Note that all of the operators in this syntactic category appear in
>the top row of the table on page 53, _except_ the ++ and --.
>According to the above grammar, the postfix forms have a precedence
>and associativity that is equal to that of -> . () and [].

The precedence/associativity table doesn't have to follow the grammar exactly,
it just has to make the right predictions. The table on page 53 does that.

>Note that some other operators appear twice in the table; for
>example * is used for multiplication and dereferencing, and
>has different precedences for each, so it appears in two
>rows. The ++ and -- should also.
>
>I don't recall ever having seen this as the subject of an errata
>list for this book, so you may have contributed to the discovery
>of a hitherto unrecognized K&R2 bug!

There is no bug. If you followed the ANSI grammar exactly you would also have
to put the cast operator at a lower precedence level than the other
unary operators. However there's simply no need to do this.

r...@cs.wisc.edu

unread,
Jun 19, 1998, 3:00:00 AM6/19/98
to

In article <898206...@genesis.demon.co.uk>,

fr...@genesis.demon.co.uk wrote:
>
> In article <6m9a3h$9...@espresso.cafe.net> k...@cafe.net "Kaz Kylheku" writes:
> >There is in fact a flaw in the book, because the ++ and -- operators
> >fail to appear in the top row of the table.
>
> There's no reason why they should.

Consistency with the grammar, and explicitly indicating that ++ and -- can
be both prefix and postfix operators, are two reasons. Also, associativity,
which has doubtful applicability to unary operators, could then be
omitted for the first two rows of the table (if you don't mix postfix and
prefix at the same level, there's only one order in which unary operators
can be applied: nearest first).

--
MJSR

Dave Hansen

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

On Wed, 17 Jun 1998 16:37:01 GMT, jc6...@acs.brockport.edu (John
Christensen) wrote:

[...]


>To tell the truth, I think there may be another, less-happy answer for
>this one. After checking The ANSI C Programming Language(Kerningham &
>Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
>this? Because the * and the ++ operators both have the exact save

>precedence according to the table on page 53 of that book. Therefore I

Really? H&S3 says * (as indirection operator) is at level 15 while
postfix ++ is at level 16[*]. Prefix ++ is at level 15.

So *x++ is grouped as *(x++)

And since prefix ++ and indirection * are both right-associative, *++x
should be grouped as *(++x) and ++*x as ++(*x).

[*]In the on-line erratta for H&S3
(http://www.lysator.liu.se/c/hs-errata.html) , it states:
"p. 167 In Table 7-1, the precedence of postfix ++ and -- should
be 17 to emphasize their symmetry with the other postfix
operators. This is not a change in the semantics. "

John Potter

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

jc6...@acs.brockport.edu (John Christensen) wrote:

: To tell the truth, I think there may be another, less-happy answer for


: this one. After checking The ANSI C Programming Language(Kerningham &
: Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
: this? Because the * and the ++ operators both have the exact save
: precedence according to the table on page 53 of that book.

My copy of that book has (written in the margins :-) "prefix" for that
line which contains the prefix unary operators, and "++ -- postfix"
for the line above which contains the postfix operators.

: Therefore I


: believe the answer to this question to be that C does not define this
: behavior, and that the behavior will depend on compiler implementation.

Nope. Check the grammar and you will find it well defined and the
same as *(x++). We need to write (*x)++ when that is what we want
just as we would be forced to write (*p).f if we couldn't write p->f.

jim.h...@leitch.com

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

In article <clcm-1998...@plethora.net>,
jc6...@acs.brockport.edu (John Christensen) wrote:
[snip]

> To tell the truth, I think there may be another, less-happy answer for
> this one. After checking The ANSI C Programming Language(Kerningham &
> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> this? Because the * and the ++ operators both have the exact save
> precedence according to the table on page 53 of that book. Therefore I

> believe the answer to this question to be that C does not define this
> behavior, and that the behavior will depend on compiler implementation.
> Perhaps we could find out how the common compilers handle this?
Nah, there's gotta be some rule that specifies this behavior.

But, for the scorekeepers, MSVC5.0 behaves as I described.

> Yes, I know this completely contradicts the answer I wrote about a week
> ago. I actually looked at my C book. Also sorry if I'm missing some hugely
> obvious point.

I'm not familiar with the C standards, but is there nothing more recent than
K&r 1988?

Jim

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading

--
comp.lang.c.moderated - cl...@plethora.net

Paul Jarc

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

jc6...@acs.brockport.edu (John Christensen) writes:
> In article <clcm-1998...@plethora.net>, jim.h...@leitch.com wrote:
> > *x++: Get the value at x, then increment x
> > *++x: Increment x, then get what it points to
> > ++*x: Increment the value pointed to by x (x is not changed)
> >
> To tell the truth, I think there may be another, less-happy answer for
> this one. After checking The ANSI C Programming Language(Kerningham &
> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> this? Because the * and the ++ operators both have the exact save
> precedence according to the table on page 53 of that book. Therefore I
> believe the answer to this question to be that C does not define this
> behavior, and that the behavior will depend on compiler implementation.
> Perhaps we could find out how the common compilers handle this?
>
> Yes, I know this completely contradicts the answer I wrote about a week
> ago. I actually looked at my C book. Also sorry if I'm missing some hugely
> obvious point.

I can't say how obvious it is, but the point you've missed is
associativity. Unary operators associate right-to-left, so
(unary-operator operand unary-operator)
is equivalent to
(unary-operator(operand unary-operator))

Without associativity, any operation like `a+b+c' would also be
undefined/unspecified/implementation-defined, because it could be
either `(a+b)+c' (which it actually is) or `a+(b+c)'. Those don't
look different at first glance, but consider `1+INT_MIN+(-1)'.
Left-to-right associativity, which is specified by the standard for +,
results in the value INT_MIN. Right-to-left associativity results in
overflow.

FYI: unary operators, the conditional operator, and assignment
operators associate right-to-left; all others associate
left-to-right.


paul
--
comp.lang.c.moderated - cl...@plethora.net

Alex...@scitex.com

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

In article <clcm-1998...@plethora.net>,
jc6...@acs.brockport.edu (John Christensen) wrote:
>
> > *x++: Get the value at x, then increment x
> > *++x: Increment x, then get what it points to
> > ++*x: Increment the value pointed to by x (x is not changed)
> >
> To tell the truth, I think there may be another, less-happy answer for
> this one. After checking The ANSI C Programming Language(Kerningham &
> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> this? Because the * and the ++ operators both have the exact save
> precedence according to the table on page 53 of that book. Therefore I
> believe the answer to this question to be that C does not define this
> behavior, and that the behavior will depend on compiler implementation.
> Perhaps we could find out how the common compilers handle this?
>
> Yes, I know this completely contradicts the answer I wrote about a week
> ago. I actually looked at my C book. Also sorry if I'm missing some hugely
> obvious point.
>

You are missing associativity. Check a definitive Lawrence Kirby posting in
a parallel thread in c.l.c about operators precedence.

Regards,
Alex Krol

Andreas Schwab

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

jc6...@acs.brockport.edu (John Christensen) writes:

|> To tell the truth, I think there may be another, less-happy answer for
|> this one. After checking The ANSI C Programming Language(Kerningham &
|> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
|> this? Because the * and the ++ operators both have the exact save
|> precedence according to the table on page 53 of that book.

By your reasoning would a+b+c also be undefined.

--
Andreas Schwab "And now for something
sch...@issan.informatik.uni-dortmund.de completely different"
sch...@gnu.org
--
comp.lang.c.moderated - cl...@plethora.net

Peter Harllee, III

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

John Christensen wrote:

> To tell the truth, I think there may be another, less-happy answer for
> this one. After checking The ANSI C Programming Language(Kerningham &
> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> this? Because the * and the ++ operators both have the exact save

> precedence according to the table on page 53 of that book. Therefore I
> believe the answer to this question to be that C does not define this
> behavior, and that the behavior will depend on compiler implementation.
> Perhaps we could find out how the common compilers handle this?
>
> Yes, I know this completely contradicts the answer I wrote about a week
> ago. I actually looked at my C book. Also sorry if I'm missing some hugely
> obvious point.
>

> --John Christensen

On page 95 of the second edition of The ANSI C Programming Language(Kerningham &
Ritchie, 1988) they address this very question. From K&R:
"
*ip += 1
increments what ip points to, as do
++*ip
and
(*ip)++

The parentheses are necessary in this last example; without them, the
expression would
increment ip instead of what it points to, because unary operators like * and
++
associate right to left.
"

So to recap,
*x++, increments x and then dereferences
(*x)++, dereferences x and then increments

Pete Harllee


--
comp.lang.c.moderated - cl...@plethora.net

rkg

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

<snip>
Yes, John, (Without K&R handy) I think that association will assist in
defining the behavior.

There is a larger point to be made here. We are five levels deep in this
discussion. Readability would argue for using parentheses to make explicit
the programmers intent. I have taught this to novices and you should see
the panic over complicated constructs.

Ray

--
comp.lang.c.moderated - cl...@plethora.net

Joseph K. Barrett

unread,
Jun 20, 1998, 3:00:00 AM6/20/98
to

John, please check the left/right and in/out precedence rules, then tell us the type
and value of the returned rvalue.

Joseph.

John Christensen wrote:

> --
> comp.lang.c.moderated - cl...@plethora.net

--
comp.lang.c.moderated - cl...@plethora.net

Lawrence Kirby

unread,
Jun 21, 1998, 3:00:00 AM6/21/98
to

In article <6mdqnh$241$1...@nnrp1.dejanews.com> r...@cs.wisc.edu writes:

>In article <898206...@genesis.demon.co.uk>,
> fr...@genesis.demon.co.uk wrote:
>>
>> In article <6m9a3h$9...@espresso.cafe.net> k...@cafe.net "Kaz Kylheku" writes:
>> >There is in fact a flaw in the book, because the ++ and -- operators
>> >fail to appear in the top row of the table.
>>
>> There's no reason why they should.
>
>Consistency with the grammar, and explicitly indicating that ++ and -- can
>be both prefix and postfix operators, are two reasons. Also, associativity,
>which has doubtful applicability to unary operators,

It is perfectly reasonable to apply associativity to unary operators.
Associativity tells you whether a subexpression is bound to the operator
on its left or the one on its right (when the operators have equal
precedence). Unary operators are as good as any other in this respect.

>could then be
>omitted for the first two rows of the table (if you don't mix postfix and
>prefix at the same level, there's only one order in which unary operators
>can be applied: nearest first).

Unfortunately people try to misapply associativity in those circumstances
anyway and it just end up confising the issue. IMO it is simpler and more
natural (hence easier to remember) to have all unary operators together
and have each level of precedence simply either left or right associative.
To add a non-associative option would IMO be more confusing. I reposed
earlier in the thread a response where I explained this in more detail.

John Potter

unread,
Jun 21, 1998, 3:00:00 AM6/21/98
to

"Peter Harllee, III" <har...@ece.cmu.edu> wrote:

: On page 95 of the second edition of The ANSI C Programming Language(Kerningham &
: Ritchie, 1988) they address this very question. From K&R:


: "
: *ip += 1
: increments what ip points to, as do
: ++*ip
: and
: (*ip)++

: The parentheses are necessary in this last example; without them, the
: expression would
: increment ip instead of what it points to, because unary operators like * and
: ++
: associate right to left.

: "

That is a very nice bit of prose, but I doubt that it is correct
reasoning. The conclusion is, of course, correct. Associativity is
defined by the grammar (in the back of the book) not some table in the
descriptive part of the book. Prefix unary operators associate right
to left, but postfix unary operators associate left to right.

ip ++ ++;

is correctly parsed as (ip ++) ++ and the compiler generates a
diagnostic stating that an l-value is required for the second ++.
IMHO, K&R simply neglected to place both the prefix and postfix ++/--
operators in the table. The two versions are totally different
operators with different precedence, associativity and semantics.
They just happen to use the same symbols. This oversight has caused
endless confusion as demonstrated by this thread.

struct s { int i; }* sp;
sp++->i++; /* ((sp++)->i)++ */

Try using the table to explain why that is valid :)

Will Rose

unread,
Jun 21, 1998, 3:00:00 AM6/21/98
to

Peter Harllee, III (har...@ece.cmu.edu) wrote:
[...]

: On page 95 of the second edition of The ANSI C Programming Language
: (Kerningham & Ritchie, 1988) they address this very question. From K&R:

: "
: *ip += 1
: increments what ip points to, as do
: ++*ip
: and
: (*ip)++

: The parentheses are necessary in this last example; without them, the
: expression would
: increment ip instead of what it points to, because unary operators like *
: and ++
: associate right to left.
: "

: So to recap,


: *x++, increments x and then dereferences
: (*x)++, dereferences x and then increments

Not really:
*x++ gets whatever x points to, and then increments x.
(*x)++ gets whatever x points to, and then increments whatever x points to.
*++x increments x and then gets whatever x points to.
++*x increments whatever x points to, and then gets whatever x points to.


Will
c...@crash.cts.com
--
comp.lang.c.moderated - cl...@plethora.net

John Kugelman

unread,
Jun 21, 1998, 3:00:00 AM6/21/98
to

Andreas Schwab wrote:

>
> jc6...@acs.brockport.edu (John Christensen) writes:
>
> |> To tell the truth, I think there may be another, less-happy answer for
> |> this one. After checking The ANSI C Programming Language(Kerningham &
> |> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> |> this? Because the * and the ++ operators both have the exact save
> |> precedence according to the table on page 53 of that book.
>
> By your reasoning would a+b+c also be undefined.

How do you figure that? Even if his reasoning were correct, it doesn't
apply to a+b+c at all.

--
John Kugelman. kuge...@mnsinc.com

I believe we can change anything.
I believe in my dream.
- Joe Satriani

--
comp.lang.c.moderated - cl...@plethora.net

r...@cs.wisc.edu

unread,
Jun 21, 1998, 3:00:00 AM6/21/98
to

In article <898274...@genesis.demon.co.uk>,

fr...@genesis.demon.co.uk (Lawrence Kirby) wrote:
>
> In article <6mdqnh$241$1...@nnrp1.dejanews.com> r...@cs.wisc.edu writes:
>
> >In article <898206...@genesis.demon.co.uk>,
> > fr...@genesis.demon.co.uk wrote:
> >>
> >> In article <6m9a3h$9...@espresso.cafe.net> k...@cafe.net "Kaz Kylheku"
writes:
> >> >There is in fact a flaw in the book, because the ++ and -- operators
> >> >fail to appear in the top row of the table.
> >>
> >> There's no reason why they should.
> >
> >Consistency with the grammar, and explicitly indicating that ++ and -- can
> >be both prefix and postfix operators, are two reasons. Also, associativity,
> >which has doubtful applicability to unary operators,

Since you have nothing to say against the first two reasons, I take it you
have conceded that "no reason" was at best an exaggeration.

> It is perfectly reasonable to apply associativity to unary operators.

The "doubt" I have is that, apparently, in (a ++ --) it would require
that -- is applied first; with pass by value, this would be meaningless.
(The fact that a++ is not an lvalue makes this meaningless; but, in
the case of a precedence level containing both prefix and postfix
operators, avoiding this problem in general would require being sure
that no two postfix [prefix] operators in that level could be
applied if associativity was right to left [left to right].)

> Associativity tells you whether a subexpression is bound to the operator
> on its left or the one on its right (when the operators have equal
> precedence). Unary operators are as good as any other in this respect.

If you really believed this, why not include all of the postfix and
prefix operators in one level with right to left associativity (so
that postfix has higher precedence)? This would still be correct,
by your above definition of associativity.

The only use of associativity for unary operators is to determine
if the prefix or postfix operator is first. This is more clearly
described by separating prefix and postfix into two precedence levels.

> >could then be
> >omitted for the first two rows of the table (if you don't mix postfix and
> >prefix at the same level, there's only one order in which unary operators
> >can be applied: nearest first).
>
> Unfortunately people try to misapply associativity in those circumstances
> anyway and it just end up confising the issue. IMO it is simpler and more

Exactly; why confuse them further by including associativity? The only
reason to include this information is to disambiguate expressions like
*x++; that Kaz Kylheku believed the K&R table to be in error suggests
that it is STILL confusing.

> natural (hence easier to remember) to have all unary operators together
> and have each level of precedence simply either left or right associative.
> To add a non-associative option would IMO be more confusing. I reposed
> earlier in the thread a response where I explained this in more detail.

I never said that they would be non-associative; that is an entirely
different question (which would change the grammar). I only said that
the information could be omitted if there was no mixing of prefix and
postfix; and it could still be included (with prefix right to left,
postfix left to right) if the blank column was deemed too confusing.

The most simple and natural approach is to have all postfix operators at
the highest precedence; all prefix unary operators next; and binary
operators next in various precedence levels (with associativity specified).
This seems consistent with common notations and is followed by most
programming languages (even if it's described in confusing ways, as in
K&R's table).

--
MJSR

Lawrence Kirby

unread,
Jun 22, 1998, 3:00:00 AM6/22/98
to

In article <6mjs1i$3bp$1...@nnrp1.dejanews.com> r...@cs.wisc.edu writes:

>In article <898274...@genesis.demon.co.uk>,
> fr...@genesis.demon.co.uk (Lawrence Kirby) wrote:
>>
>> In article <6mdqnh$241$1...@nnrp1.dejanews.com> r...@cs.wisc.edu writes:
>>
>> >In article <898206...@genesis.demon.co.uk>,
>> > fr...@genesis.demon.co.uk wrote:
>> >>
>> >> In article <6m9a3h$9...@espresso.cafe.net> k...@cafe.net "Kaz Kylheku"
>writes:
>> >> >There is in fact a flaw in the book, because the ++ and -- operators
>> >> >fail to appear in the top row of the table.
>> >>
>> >> There's no reason why they should.
>> >
>> >Consistency with the grammar, and explicitly indicating that ++ and -- can
>> >be both prefix and postfix operators, are two reasons. Also, associativity,
>> >which has doubtful applicability to unary operators,
>
>Since you have nothing to say against the first two reasons, I take it you
>have conceded that "no reason" was at best an exaggeration.

I don't believe consistency with the form of the grammar is an issue.
Clearly precedence/associativity rules must predict the same expression
grouping as the grammar does. If you want the grammar you know where to find
it; it is useful for compiler (and other source code tool) writers. A
precedence/associativity table in this context (a C language tutorial or
reference) has a different role which is to make it as easy as possible for
programmers to analyse expressions in source code. Its form should be chosen
to best do that job. If that means that it doesn't follow the exact form
of the syntax then so be it - a C programmer doesn't need to know anything
about the actual syntactic production rules in the standard.

I do see the attraction of and logic behind having separate entries for
prefix and suffix ++ and --. However tht is a matter of how you look at it,
and I've never seen a problem with the K&R precedence table that was caused
by this. I have seen problems resulting from separating them out.

>> It is perfectly reasonable to apply associativity to unary operators.
>
>The "doubt" I have is that, apparently, in (a ++ --) it would require
>that -- is applied first; with pass by value, this would be meaningless.

But that isn't how precedence and associativity rules are applied. They
exist to resolve ambiguity where it exists and in this case none exists.
Even with your method you have to deal with something like

a ? b = d : c = d

which groups as

(a ? (b = d) : c) = d

b = d groups together even though ?: has higher precedence than =, so this
isn't a principle that your approach allows you to ignore.

>(The fact that a++ is not an lvalue makes this meaningless; but, in
>the case of a precedence level containing both prefix and postfix
>operators, avoiding this problem in general would require being sure
>that no two postfix [prefix] operators in that level could be
>applied if associativity was right to left [left to right].)

Right associativity of the unary operators means that operators to the right
of an expression bind more tightly to operators on the left. Withing a
group of operators on the left or operators on the right the binding is
unambiguous.

>> Associativity tells you whether a subexpression is bound to the operator
>> on its left or the one on its right (when the operators have equal
>> precedence). Unary operators are as good as any other in this respect.
>
>If you really believed this,

I accept the definition and usage in references like the Dragon book.

>why not include all of the postfix and
>prefix operators in one level with right to left associativity (so
>that postfix has higher precedence)? This would still be correct,
>by your above definition of associativity.

That is exactly what I'm arguing for and what K&R does. I posted the K&R
precedence table recently. It is easy to remember because all unary operators
are at the same precedence level and are right associative.

>The only use of associativity for unary operators is to determine
>if the prefix or postfix operator is first. This is more clearly
>described by separating prefix and postfix into two precedence levels.

Both approaches say that operators on the right take precedence. I might
argue that right associativity is the more direct statement of this. The K&R
approach has the nice property that each level of precedence has a
characteristic direction of association: either left or right with no
odd exceptions. All operators in a precedence level take the same number
of operands. All binary operators except assignment are left associative.
All non-binary operators are right associative. It is easy to generalise
and remember. It makes it easy to interpret something like:

a>b ? 1 : a==b ? 0 : -1;

Is it like

(a>b ? 1 : a==b) ? 0 : -1;

or

a>b ? 1 : (a==b ? 0 : -1);

>> >could then be
>> >omitted for the first two rows of the table (if you don't mix postfix and
>> >prefix at the same level, there's only one order in which unary operators
>> >can be applied: nearest first).
>>
>> Unfortunately people try to misapply associativity in those circumstances
>> anyway and it just end up confising the issue. IMO it is simpler and more
>
>Exactly; why confuse them further by including associativity?

The problem is that people try to apply associativity even when it doesn't
apply. If you have King's book take a look. People have to know about
associativity to aplly a precedence table properly. Having precedence levels
with no associativity is surprising and unexpected. That is what causes the
problem.

> The only
>reason to include this information is to disambiguate expressions like
>*x++; that Kaz Kylheku believed the K&R table to be in error suggests
>that it is STILL confusing.

Kaz just said that it didn't have the same form as the ANSI grammar. I don't
want to 2nd guess him but I suspect that the only confusing thing is the
assumption that it should have the same form. If you follow that principle
then you need to give the cast operator its very own precedence level which
I think is too subtle a point for a precedence table. Remember also that the
standard's production rules are based on the K&R1 precedence table or at
least the syntax summary in appendix A.18 which is still partly precedence
based.

>> natural (hence easier to remember) to have all unary operators together
>> and have each level of precedence simply either left or right associative.
>> To add a non-associative option would IMO be more confusing. I reposed
>> earlier in the thread a response where I explained this in more detail.
>
>I never said that they would be non-associative; that is an entirely
>different question (which would change the grammar). I only said that
>the information could be omitted if there was no mixing of prefix and
>postfix; and it could still be included (with prefix right to left,
>postfix left to right) if the blank column was deemed too confusing.

If you group just the prefix unary operators together and just the
postfix unary operators then they really do have no associativity. If
you don't label them with a direction of association it looks odd, if you
do it is misleading.

>The most simple and natural approach is to have all postfix operators at
>the highest precedence; all prefix unary operators next; and binary
>operators next in various precedence levels (with associativity specified).

This fails with for example a->b++ or ++a->b or ++p[i]

>This seems consistent with common notations and is followed by most
>programming languages (even if it's described in confusing ways, as in
>K&R's table).

It is at least correct! :-) What is confusing about it?

r...@cs.wisc.edu

unread,
Jun 25, 1998, 3:00:00 AM6/25/98
to

In article <898558...@genesis.demon.co.uk>,

fr...@genesis.demon.co.uk wrote:
>
> In article <6mjs1i$3bp$1...@nnrp1.dejanews.com> r...@cs.wisc.edu writes:
>
> >In article <898274...@genesis.demon.co.uk>,
> > fr...@genesis.demon.co.uk (Lawrence Kirby) wrote:
> >>
> >> In article <6mdqnh$241$1...@nnrp1.dejanews.com> r...@cs.wisc.edu writes:
> >>
> >> >In article <898206...@genesis.demon.co.uk>,
> >> > fr...@genesis.demon.co.uk wrote:
> >> >>
> >> >> In article <6m9a3h$9...@espresso.cafe.net> k...@cafe.net "Kaz Kylheku"
> >writes:
> >> >> >There is in fact a flaw in the book, because the ++ and -- operators
> >> >> >fail to appear in the top row of the table.
> >> >>
> >> >> There's no reason why they should.
> >> >
> >> >Consistency with the grammar, and explicitly indicating that ++ and -- can
> >> >be both prefix and postfix operators, are two reasons. Also, associativity,
> >> >which has doubtful applicability to unary operators,
> >
> >Since you have nothing to say against the first two reasons, I take it you
> >have conceded that "no reason" was at best an exaggeration.
>
> I don't believe consistency with the form of the grammar is an issue.

Consistency with the standard is always an issue. There are two potential
problems: someone familiar with the table has cause to read the grammar
and is confused by the inconsistency; an implementation provides an
operator as an extension and specifies the precedences in terms of the
existing operators. If this implementation added $ as a unary operation
with precedence between the postfix operator ++ and the prefix operator
++, then the K&R table would lead to some confusion (but the extension
would still make sense with respect to the standard, which is what is
being extended).

Yes, neither of these is very significant, but I'm arguing only that these
are reasons for a different precedence table, not that they are particularly
compelling.

> Clearly precedence/associativity rules must predict the same expression
> grouping as the grammar does. If you want the grammar you know where to find
> it; it is useful for compiler (and other source code tool) writers. A

Yes, you can find the grammar in K&R (the appendix); in many other
language (C and others) references, it's embedded in the main text
as well. A similar argument would say that nobody but compiler (and
other source code tool) writers needs the language standard; but this
is a rather old-fashioned view. Certainly the ability to read a BNF
grammar is a very basic skill for any programmer.

> precedence/associativity table in this context (a C language tutorial or
> reference) has a different role which is to make it as easy as possible for
> programmers to analyse expressions in source code. Its form should be chosen
> to best do that job. If that means that it doesn't follow the exact form
> of the syntax then so be it - a C programmer doesn't need to know anything
> about the actual syntactic production rules in the standard.

The standard defines precedence levels. The table says something
different. By the same reasoning, C tutorials and references could use a
different terminology than "byte". It would be more efficient to define a
different name for this and avoid the confusion with other uses of "byte",
but the programmer using the tutorial or reference would not be served
well by this.

> I do see the attraction of and logic behind having separate entries for
> prefix and suffix ++ and --. However tht is a matter of how you look at it,
> and I've never seen a problem with the K&R precedence table that was caused
> by this. I have seen problems resulting from separating them out.

The current thread is not a problem? (The confusion that started this
particular branch was apparently caused by the lack of separation.)

> >> It is perfectly reasonable to apply associativity to unary operators.
> >
> >The "doubt" I have is that, apparently, in (a ++ --) it would require
> >that -- is applied first; with pass by value, this would be meaningless.
>
> But that isn't how precedence and associativity rules are applied. They
> exist to resolve ambiguity where it exists and in this case none exists.

Well, I have to admit that I was able to parse *x++ back in K&R C using
the K&R table without a problem, so my argument is a bit weak here.
Maybe even a lot weak. But I still don't much like lumping prefix and
postfix operators at the same precedence and then using associativity
in place of precedence.

> Right associativity of the unary operators means that operators to the right
> of an expression bind more tightly to operators on the left. Withing a
> group of operators on the left or operators on the right the binding is
> unambiguous.
>
> >> Associativity tells you whether a subexpression is bound to the operator
> >> on its left or the one on its right (when the operators have equal
> >> precedence). Unary operators are as good as any other in this respect.
> >
> >If you really believed this,
>
> I accept the definition and usage in references like the Dragon book.

But I can find no example in the Dragon book in which associativity is
applied to unary operators (although there's no example of a ternary
operator, either); nor can I think of another language definition that
uses associativity to specify the relative precedence of prefix and
postfix operators. Mathematically, associativity arises from the
associative law, which is about binary operators.

> >why not include all of the postfix and
> >prefix operators in one level with right to left associativity (so
> >that postfix has higher precedence)? This would still be correct,
> >by your above definition of associativity.
>
> That is exactly what I'm arguing for and what K&R does. I posted the K&R
> precedence table recently. It is easy to remember because all unary operators
> are at the same precedence level and are right associative.

No, it doesn't do this. The postfix operators are those defined in the
grammar non-terminal postfix-expression; specifically,
[ expression ]
( argument-expression-list_opt )
. identifier
-> identifier
++
--
Perhaps this was unclear. Although some of these do not appear to be
unary operators, they are parameterized unary postfix operators for
purposes of precedence (only the single operand preceding each is
relevant for precedences, since lower precedence operators within
( ) or [ ] are resolved first). I realize that my enlightened view on this
matter will undoubtedly appear to be utterly wrong; perhaps I've written
too many compilers. Right to left associativity with -> and . would be a
problem if you view the field identifier as an operand, though.

In any event, function call with no arguments is a unary postfix operator
but is not at the same level as the other unary operators in the K&R table.

> >The only use of associativity for unary operators is to determine
> >if the prefix or postfix operator is first. This is more clearly
> >described by separating prefix and postfix into two precedence levels.
>
> Both approaches say that operators on the right take precedence. I might
> argue that right associativity is the more direct statement of this. The K&R
> approach has the nice property that each level of precedence has a
> characteristic direction of association: either left or right with no
> odd exceptions.

Putting postfix ++ and -- in the first row would preserve this property.

> All operators in a precedence level take the same number
> of operands.

This property is already missing from the first row, since ( ) has a variable
number of operands. Clearly, it has only one operand in f() and has two
in f(a). (Perhaps you are stretching the meaning of operand to be
"a subexpression OR a possibly empty argument list OR the name
of a structure or union field". The niceness of the property is certainly
offset by the ugliness of this definition of operand. The C9X standard
describes operand as an entity on which an operator acts, but I can't
find whether it treats argument lists (empty or not) as a single
entity.)

> All binary operators except assignment are left associative.
> All non-binary operators are right associative. It is easy to generalise
> and remember. It makes it easy to interpret something like:
>
> a>b ? 1 : a==b ? 0 : -1;

These rules are an argument for the K&R table that I had not considered,
but they still depend on treating ( ) as a binary operator.

Associativity is not hard to remember; do you have a good trick for
remembering the relative precedence of << >> & ^ | in the middle
of the table? THAT would be useful. (I always parenthesize them,
and I don't use them that often; but it would help in reading other
people's code.)

> > The only
> >reason to include this information is to disambiguate expressions like
> >*x++; that Kaz Kylheku believed the K&R table to be in error suggests
> >that it is STILL confusing.
>
> Kaz just said that it didn't have the same form as the ANSI grammar. I don't

Well, he's even quoted above (I think correctly) as saying there is a
flaw in the table; he described it in another post as an error in K&R.

> want to 2nd guess him but I suspect that the only confusing thing is the
> assumption that it should have the same form. If you follow that principle
> then you need to give the cast operator its very own precedence level which

Well, by my previous argument for consistency with the standard, you
should. And if the standard gave every unary prefix operator a separate
precedence, then probably they should each have a separate row (but
it would also be appropriate to criticize the standard for needlessly
creating additional precedence levels, which seems to be the case with
casts).

Of course, casts are treated separately because of a different problem; it
is unfortunate that this led to a separate precedence level. (The problem,
of course, is that sizeof applied to a cast of an expression would conflict
with sizeof applied to a type name in parentheses.)

> I think is too subtle a point for a precedence table. Remember also that the
> standard's production rules are based on the K&R1 precedence table or at
> least the syntax summary in appendix A.18 which is still partly precedence
> based.

But the standard's production rules made substantial changes to A.18 (which
specifies the wrong associativity for ? :, at least in the copy I have). In
K&R1, postfix and prefix ++ were at the same level of precedence. The
standard moved the postfix ++ and -- operators into a different section,
giving them higher precedence. K&R2 describes this different precedence in
appendix A, but didn't make all of the resulting changes to the precedence
table.

The grammar in A.18 does not specify precedence in the grammar,
except that the productions are in precedence order; it specifies
precedence and associativity separately (and as noted, lists the
wrong associativity for the conditional operator).

> >> natural (hence easier to remember) to have all unary operators together
> >> and have each level of precedence simply either left or right associative.
> >> To add a non-associative option would IMO be more confusing. I reposed
> >> earlier in the thread a response where I explained this in more detail.
> >
> >I never said that they would be non-associative; that is an entirely
> >different question (which would change the grammar). I only said that
> >the information could be omitted if there was no mixing of prefix and
> >postfix; and it could still be included (with prefix right to left,
> >postfix left to right) if the blank column was deemed too confusing.
>
> If you group just the prefix unary operators together and just the
> postfix unary operators then they really do have no associativity. If
> you don't label them with a direction of association it looks odd, if you
> do it is misleading.

So we have to confuse the precedence levels just to be sure that
associativity is needed at each level?

> >The most simple and natural approach is to have all postfix operators at
> >the highest precedence; all prefix unary operators next; and binary
> >operators next in various precedence levels (with associativity specified).
>
> This fails with for example a->b++ or ++a->b or ++p[i]

But ->identifier and [expression] are postfix operators. The only change
in this approach is that postfix ++ and -- go into the top row. I also
neglected to mention the ternary operator (which would go in its usual
place among the binary operators. (I have trouble viewing . as a binary
operator; perhaps if I could write a.(b) I would feel differently.)

So, let me rephrase that: postfix operators; then prefix unary operators;
then binary and ternary operators excluding those that are among
the postfix operators. Most languages follow this pattern (if they have
comparable expression syntax): APL is an exception but can hardly
be called natural.

(Some languages give higher precedence to an exponentiation
operator than unary minus, but this is because the exponentiation
operator is trying to act like superscripting in a mathematical formula.
A better way of expressing this would be a postfix operator like [ ]
that represented a superscript; in Algol 60, the notation a[b] could
be replaced in the publication language by typesetting b as an
actual subscript of a and omitting the brackets.)

I guess that "simple" has proven to be wrong, though.

> >This seems consistent with common notations and is followed by most
> >programming languages (even if it's described in confusing ways, as in
> >K&R's table).
>
> It is at least correct! :-) What is confusing about it?

What's confusing? The quoting at the start of this post is six levels deep,
and it all seems to stem from somebody's earlier confusion in reading the
K&R table.

Andreas Schwab

unread,
Jul 1, 1998, 3:00:00 AM7/1/98
to

John Kugelman <kuge...@mnsinc.com> writes:

|> Andreas Schwab wrote:
|> >
|> > jc6...@acs.brockport.edu (John Christensen) writes:
|> >
|> > |> To tell the truth, I think there may be another, less-happy answer for
|> > |> this one. After checking The ANSI C Programming Language(Kerningham &
|> > |> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
|> > |> this? Because the * and the ++ operators both have the exact save
|> > |> precedence according to the table on page 53 of that book.
|> >
|> > By your reasoning would a+b+c also be undefined.
|>
|> How do you figure that? Even if his reasoning were correct, it doesn't
|> apply to a+b+c at all.

This expression involves two operators with equal precedence at the same
level, thus it must be undefined by his argument.

Lawrence Kirby

unread,
Jul 1, 1998, 3:00:00 AM7/1/98
to

In article <clcm-1998...@plethora.net>
kuge...@mnsinc.com "John Kugelman" writes:

>Andreas Schwab wrote:
>>
>> jc6...@acs.brockport.edu (John Christensen) writes:
>>
>> |> To tell the truth, I think there may be another, less-happy answer for
>> |> this one. After checking The ANSI C Programming Language(Kerningham &
>> |> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
>> |> this? Because the * and the ++ operators both have the exact save
>> |> precedence according to the table on page 53 of that book.
>>
>> By your reasoning would a+b+c also be undefined.
>
>How do you figure that? Even if his reasoning were correct, it doesn't
>apply to a+b+c at all.

Consider a-b+c then. The problem was that he ignored associativity. In that
case he couldn't disambiguate between (*x)++ and *(x++). By the same
reasoning this would be ambiguous between (a-b)+c and a-(b+c) since + and -
have the same precedence. Even (a+b)+c and a+(b+c) could produce different
results (or different failure circumstances due to overflow) if a,b and c
don't all have the same type.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------

--
comp.lang.c.moderated - cl...@plethora.net

John R Hines

unread,
Jul 16, 1998, 3:00:00 AM7/16/98
to
Remember, unary operators are right to left associative:

*x++ says "increment x at last possible minute and get the value of the
variable x points at"

(*x)++ says "at the last possible moment, increment the value of the
variable the pointer points at"

//testcase.cpp

main( )
{
int aiX[2]= {3, 33}, iZ, *piZ;
piZ = aiX
iZ = *piY ++; //increment pointer at last moment and coopy *piY into
iZ;
cout << "*x++: iZ is " << iZ << "and *piY is "
<< *piY;//predict "iZ is 3 and *piY is 33"
//piY was incremented so it now points at aiX[1] instead of aiX[0]!
piZ = aiX
iZ = (*piY)++; //increment value of *piY after assignment of *piY to
iZ
cout << "(*x)++: iZ is " << iZ << "and *piY is " << *piY;//predict "iZ
is 3 and *piY is 3"
//*piY was incremented (after the assignment) but piY still points
aiX[0]!
//interesting question: what happens, if anything, to aiX[0] due to
(*x)++? I think it is now 4????
return 0;
}


Andreas Schwab wrote in message ...


>John Kugelman <kuge...@mnsinc.com> writes:
>
>|> Andreas Schwab wrote:
>|> >
>|> > jc6...@acs.brockport.edu (John Christensen) writes:
>|> >
>|> > |> To tell the truth, I think there may be another, less-happy answer
for
>|> > |> this one. After checking The ANSI C Programming Language(Kerningham
&
>|> > |> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do
I say
>|> > |> this? Because the * and the ++ operators both have the exact save
>|> > |> precedence according to the table on page 53 of that book.
>|> >
>|> > By your reasoning would a+b+c also be undefined.
>|>
>|> How do you figure that? Even if his reasoning were correct, it doesn't
>|> apply to a+b+c at all.
>

>This expression involves two operators with equal precedence at the same
>level, thus it must be undefined by his argument.
>
>--
>Andreas Schwab "And now for something
>sch...@issan.informatik.uni-dortmund.de completely different"
>sch...@gnu.org
>--
>comp.lang.c.moderated - cl...@plethora.net

--
comp.lang.c.moderated - cl...@plethora.net

Darlene&Bob Winkelman

unread,
Jul 16, 1998, 3:00:00 AM7/16/98
to
Same precedence, different associativity:

"Unary operators and assignment operators are right associative; all others are left
associative. That is, a=b=c means a=(b=c), a+b+c means (a+b)+c, and *p++ means
*(p++), not (*p)++."
from the C++ Programming Language 2nd Ed., Stroustrup, 3.2 Operator Summary, second
paragraph.

Of course, the pointer only gets incremented after it is dereferenced, but it is the
pointer which gets
incremented, not the value it points to.

--
comp.lang.c.moderated - cl...@plethora.net

David Sambell

unread,
Jul 16, 1998, 3:00:00 AM7/16/98
to

Andreas Schwab wrote:

> John Kugelman <kuge...@mnsinc.com> writes:
>
> |> Andreas Schwab wrote:
> |> >
> |> > jc6...@acs.brockport.edu (John Christensen) writes:
> |> >
> |> > |> To tell the truth, I think there may be another, less-happy answer for
> |> > |> this one. After checking The ANSI C Programming Language(Kerningham &
> |> > |> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> |> > |> this? Because the * and the ++ operators both have the exact save
> |> > |> precedence according to the table on page 53 of that book.
> |> >
> |> > By your reasoning would a+b+c also be undefined.
> |>
> |> How do you figure that? Even if his reasoning were correct, it doesn't
> |> apply to a+b+c at all.
>
> This expression involves two operators with equal precedence at the same
> level, thus it must be undefined by his argument.

Correct me if I'm wrong, but he stated that 2 *different* operators have the same
precedence, namely * and ++
a+b+c uses 2 operators which are the same and thus not applicable.
Say if + and - had the same precedence, how could not then define a+b-c. Is it
(a+b)-c or a-(b+c)?
--
comp.lang.c.moderated - cl...@plethora.net

Steven Moy

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
David Sambell (david....@dsto.defence.gov.au) wrote:


: Andreas Schwab wrote:

I just whipped out good ol' K&R, and I found the following passage:
"The unary operators * and & bind more tightly than arithmetic oerators,
so the assignment
y = *ip + 1
takes whatever ip points at, adds 1, and assigns the result to y, while


*ip += 1
increments what ip points to, as do
++*ip
and
(*ip)++"

here's the important part...


"The parentheses are necessary in this last example; without them,
the expression would increment ip instead of what it points to, because

unary operators like * and ++ associate right to left." -K&R p.95

So it has been written...
So it shall be done...

concerning the a+b-c example, + and - have the same precendence. It doesn't
make a big difference which you do first (except in the case of overflow)
so by convention it is done from left to right.

--
Steven Moy
Georgia Institute of Technology
sm...@cc.gatech.edu
--
comp.lang.c.moderated - cl...@plethora.net

John Hines

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
Four points:
1. Unlike K&R in the old days, AK&R is not the definition of ANSI Standard
C so anything in it is speculation just as it would be in any other book
unless it is matched up to text in the ANSI C Standard. WHAT DOES THE ANSI
C STANDARD SAY?

2. At the risk of sounding stupider than I am, I have to argue that y'all
missed the point. There are three rules for eliminating operators from
expressions, hierarchy, associativity and alignment and you have to pay
attention to all of them. (Well , you can blow off alignment if the
expression doesn't contain ++ or --.)

Hierarchy (precedence) is the rule for breaking operators into "execution"
groups. Expressions are simplified by eliminating operators of the same
group one at a time.

Associativity (correct term? think so but not sure) defines the rule for
for eliminating operators of the same group.
For all except unary and assignment operators, operators
of the same group are eliminated one at a time from left to
right. So,
a +b*c is same as a + ( b* c )
(different hierarchies) while
a+b-c is same as (a+b) - c.
(same hierarchy). However, unary and assignment operators
are eliminated right to left. So,
a=b=c is same as a = (b=c)
Alignment only applies to ++ and --: when ++ and -- are on the left they
are "Democratic" operators demanding instant execuation while when they are
on the right the are "Repulican" operators demainding delay of execution
until all other operators have been eliminated. So,
(I contend)
printf( "%i", *x++) ; is same as printf( "%i", * x) followed by
x++

3. Did my demo program produce the predicted results? (A compiler is more
"standard" than any "book" except the Standard.)

4. Another way of "proving" Christensen's argument would be to find a
compiler that rejects the statement
y=*px++;
Is there one?

John

David Sambell wrote in message ...

--
comp.lang.c.moderated - cl...@plethora.net

Richard Stamp

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
In article <clcm-1998...@plethora.net>,
Darlene&Bob Winkelman <u7...@www.snet.net> wrote:
[about postfix vs. prefix ++]
>Same precedence, different associativity:

[I'm reading this in comp.lang.c, so this is a C-centric comment.]

It really doesn't matter. You can look at postfix ++ as having higher
precedence, or you can look at it as having the same precedence with
associativity resolving ambiguities. Both these models work fine and
there are examples of books which use each approach (e.g. K&R has them
at the same precedence, Harbison & Steele has them at different
precedences -- in the latter case there appears to be a typo in some
editions, which rather adds to the confusion).

If you say they have different levels of precedence, though, it then
doesn't make sense to talk about associativity for the unary operators
(since there's never any ambiguity to be resolved by application of
associativity). Many authors, including H&S and apparently King, make
the mistake of separating postfix and prefix but also trying to specify
an order of associativity.

Some claim that the lack of symmetry in the "different precedence"
approach (i.e. associativity is relevant for some operators but not for
others) means that this approach is inferior; others disagree.

Cheers,
Richard
--
Richard Stamp
Churchill College, Cambridge
--
comp.lang.c.moderated - cl...@plethora.net

jim.h...@leitch.com

unread,
Jul 20, 1998, 3:00:00 AM7/20/98
to
In article <clcm-1998...@plethora.net>,
David Sambell <david....@dsto.defence.gov.au> wrote:
>
[snp]

> Correct me if I'm wrong, but he stated that 2 *different* operators have the
same
> precedence, namely * and ++
> a+b+c uses 2 operators which are the same and thus not applicable.
> Say if + and - had the same precedence, how could not then define a+b-c. Is it
> (a+b)-c or a-(b+c)?
Precedence is not the only key - you also have associativity. Binary + and -
are evaluated from left-to-right. Thus a+b-c must behave according to the
mathematical rules set down so many years ago, i.e.: (a+b)-c.

Jim

-----== Posted via Deja News, The Leader in Internet Discussion ==-----

http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
--
comp.lang.c.moderated - cl...@plethora.net

Mike Percy

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to
David Sambell wrote:

> Andreas Schwab wrote:
>
> > John Kugelman <kuge...@mnsinc.com> writes:
> >
> > |> Andreas Schwab wrote:
> > |> >
> > |> > jc6...@acs.brockport.edu (John Christensen) writes:
> > |> >
> > |> > |> To tell the truth, I think there may be another, less-happy answer for
> > |> > |> this one. After checking The ANSI C Programming Language(Kerningham &
> > |> > |> Ritchie, 1988), I believe the behavior of *x++ is undefined. Why do I say
> > |> > |> this? Because the * and the ++ operators both have the exact save
> > |> > |> precedence according to the table on page 53 of that book.
> > |> >
> > |> > By your reasoning would a+b+c also be undefined.
> > |>
> > |> How do you figure that? Even if his reasoning were correct, it doesn't
> > |> apply to a+b+c at all.
> >
> > This expression involves two operators with equal precedence at the same
> > level, thus it must be undefined by his argument.
>

> Correct me if I'm wrong, but he stated that 2 *different* operators have the same
> precedence, namely * and ++
> a+b+c uses 2 operators which are the same and thus not applicable.
> Say if + and - had the same precedence, how could not then define a+b-c. Is it
> (a+b)-c or a-(b+c)?

> --
> comp.lang.c.moderated - cl...@plethora.net

That's why most tables of operator precedence also include a column for
associativity. Associativity (left to right or right to left) determines how, in the
absence of paretheses, the compiler resolves the grouping of expressions with
operators of equal precedence. Since * and ++ are the same precedence, and associate
right-to-left, we know that *x++ is not undefined, but will resolve as if it had been
written *(xx++). That is, dereference x to obtain a value, v, then at the next
sequence point, increment the pointer x. This is different from (*x)++, which say
dereference x to obtain a value, v, which is then incremented at the next sequence
point.

In the case of a+b-c, those operators are at the same level of precedence, with
left-to-right associativity, resolves as if it had been written (a+b) - c.

--
comp.lang.c.moderated - cl...@plethora.net

Richard Stamp

unread,
Jul 21, 1998, 3:00:00 AM7/21/98
to
In article <clcm-1998...@plethora.net>,

John Hines <jhi...@autotester.com> wrote:
>Four points:
>1. Unlike K&R in the old days, AK&R is not the definition of ANSI Standard
>C so anything in it is speculation just as it would be in any other book
>unless it is matched up to text in the ANSI C Standard. WHAT DOES THE ANSI
>C STANDARD SAY?

The C Standard doesn't use the terms "precedence" and "associativity", but
it expresses the same concepts in the form of its grammar. The bottom
line is that it agrees with everybody else and says that *x++ means *(x++).

>2. At the risk of sounding stupider than I am, I have to argue that y'all
>missed the point.

With respect, I think the point is subtler than you realise. The best way
to deal with unary operators in the precedence/associativity hierarchy
is by no means agreed on. Witness the fact that different authors do it
different ways. All that *really* matters is that you get the right
results from the system, which in this case means that postfix ++ binds
more tightly than unary *.

*Any* (reasonable) way of expressing this is fine: you can say the unary
operators associate right to left, you can say postfix ++ has a higher
precedence, or you can express it as a grammar, as is done in the Standard.

This thread is quite convoluted and hard to follow, so I really don't
know whether I'm agreeing or disagreeing with you. :-)

>Alignment only applies to ++ and --: when ++ and -- are on the left they
>are "Democratic" operators demanding instant execuation while when they are
>on the right the are "Repulican" operators demainding delay of execution
>until all other operators have been eliminated.

Heh. This is a pretty witty metaphor.

This doesn't have anything to do with precedence/associativity, though.
You can work out the fully-parenthesised form of an expression from a
precedence/associativity table without knowing anything about what the
operators actually do. The above really just says that postfix and
prefix ++ (or --) do different things, which is an important thing to
know but doesn't help us understand how they bind to other operators.

>(I contend)
> printf( "%i", *x++) ; is same as printf( "%i", * x) followed by
>x++

That's right (there might be some very subtle issues to do with sequence
points but that's well outside the scope of this discussion). In other
words, *x++ means *(x++): dereference the original value of x, and
increment x.

>3. Did my demo program produce the predicted results? (A compiler is more
>"standard" than any "book" except the Standard.)

Mm, debatable. For a simple issue like this that's probably true, but in
general I think a good book wins. In particular relying on a compiler
may give you the false impression that something is OK when actually it
just "happens to work" (i.e. the behaviour is really undefined).

>4. Another way of "proving" Christensen's argument would be to find a
>compiler that rejects the statement
> y=*px++;
>Is there one?

John (Christiensen) was wrong to think that *x++ was undefined *but* you
can't prove him wrong by pointing at any number of compilers. Such is
the nature of undefined behaviour. As you say yourself at the top, all
that can help you here is what the Standard says (though checking one
or more reputable books, this being basically equivalent to asking
someone knowledgeable whom you trust, will give you a very good idea).

[Incidentally, a side benefit of the repeated discussion of this issue
over the past few months is that it's finally drummed "*x++ is *(x++)"
into my poor, impenetrable little brain. Previously I had to look it
up every time. :-)]

0 new messages