473,387 Members | 1,641 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

associativity question

Associativity in C takes two forms: left to right and right to left. I
think the K&R book lacks something...

For example, *p++, since the associativity is from right to left, do
this expression means *(p++)? I think I am wrong. (so, associativity
is not for operand?)

But for *++p, right to left associativity means *(++p) is correct.

So by definition of associativity, I guess it only applys on grouped
operators but not on operand. Right? A more complicated example will
be char* const *(*next++)()

Feb 6 '07 #1
5 2091
fd*******@gmail.com said:
Associativity in C takes two forms: left to right and right to left. I
think the K&R book lacks something...

For example, *p++, since the associativity is from right to left, do
this expression means *(p++)?
Yes.
But for *++p, right to left associativity means *(++p) is correct.
Yes, except for the "But", which should be "And".

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Feb 6 '07 #2
Richard Heathfield wrote:
fd*******@gmail.com said:
>Associativity in C takes two forms: left to right and right to
left. I think the K&R book lacks something...

For example, *p++, since the associativity is from right to
left, do this expression means *(p++)?

Yes.
>But for *++p, right to left associativity means *(++p) is correct.

Yes, except for the "But", which should be "And".
In both cases the OP should think about the value of the beast
encased in parentheses.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Feb 6 '07 #3
fd*******@gmail.com wrote:
Associativity in C takes two forms: left to right and right to left. I
think the K&R book lacks something...
OK. Although the syntax (and semantics) of expressions in C is officially
described by the language grammar, in most cases it can be described in
simplified terms of operator "associativity" and "precedence".
For example, *p++, since the associativity is from right to left,
do
this expression means *(p++)? I think I am wrong. (so, associativity
is not for operand?)
There's no associativity involved in this case. Associativity is only applicable
to binary operators. In this case it is about precedence only. Postfix operators
normally take precedence over prefix operators. That's why it means '*(p++)'.
But for *++p, right to left associativity means *(++p) is correct.
Once again, no associativity involved here. Moreover, in this particular case
there's no need to involve either associativity or precedence.

Associativity and/or precedence come into play when the meaning of the
expression is potentially ambiguous, i.e. there are several ways to assign
precedences and associate operands with operators. In order to be ambiguous it
has to involve multiple binary/ternary operators, or a mix of prefix and postfix
unary operators applied to the same operand, or a mix of unary and
binary/ternary operators.

There's nothing like that in case of '*++p'. There's only one way to parse it.
It's *(++p)'. No need (and no way) to involve precedence or associativity at all.
So by definition of associativity, I guess it only applys on grouped
operators but not on operand. Right?
Associativity applies when you have a long "chain" of binary operators of equal
precedence. It's associativity that tells you that 'a - b + c' means '(a - b) +
c' and not 'a - (b + c)'.
A more complicated example will
be char* const *(*next++)()
This just doesn't make sense in C. At the first sight it looks like a
declaration, but you can't have a '++' in a declaration (at least not the way
you used it above).

--
Best regards,
Andrey Tarasevich
Feb 7 '07 #4
Andrey Tarasevich <an**************@hotmail.comwrites:
fd*******@gmail.com wrote:
>Associativity in C takes two forms: left to right and right to left. I
think the K&R book lacks something...

OK. Although the syntax (and semantics) of expressions in C is officially
described by the language grammar, in most cases it can be described in
simplified terms of operator "associativity" and "precedence".
>For example, *p++, since the associativity is from right to left,
do
this expression means *(p++)? I think I am wrong. (so, associativity
is not for operand?)

There's no associativity involved in this case. Associativity is
only applicable to binary operators.
Associativity (or something very like it) is applicable in expressions
with unary operators if pre- and postfix operators are mixed.

*p++ could be ((*p)++) or (*(p++))

In their operator table K&R list * and ++ as right associative so the
above is interpreted as we all know it is.
In this case it is about precedence only. Postfix operators
normally take precedence over prefix operators.
Not according to K&R. They list them in the same row -- i.e. as
having the same precedence. As you say, non of this is "official",
but it is the source of the OP's question. In fact on page 91[1] they
explain that to increment what p points to you must write (*p)++
because "unary operations like * and ++ are evaluated right to left".

[1] My copy is K&R 1978(!).

--
Ben.
Feb 7 '07 #5
>fd*******@gmail.com wrote:
>>Associativity in C takes two forms: left to right and right to left. I
think the K&R book lacks something...
>Andrey Tarasevich <an**************@hotmail.comwrites:
>OK. Although the syntax (and semantics) of expressions in C is officially
described by the language grammar, in most cases it can be described in
simplified terms of operator "associativity" and "precedence".
Simplified for humans, anyway. Computers can do it either way. :-)

More specifically, the task at hand is to bind operators to operands,
so as to build a "parse tree" (see, e.g.,
<http://en.wikipedia.org/wiki/Parsing>, which has a little graphic
of how to bind "1 + 2 * 3" in the usual manner). If one uses an
"operator precedence grammar", to simplify the idea for humans,
one must specify the "precedence" of the various operators, hence
the name "operator precedence grammar".

As Andrey Tarasevich noted, the C standards (C89 and C99 both) use
a different method, so that Standard C does not need to talk about
precedence and associativity at all. (It still uses those words
anyway, since the grammar in the standard has an implied equivalent
operator-precedence grammar. In fact, it actually has multiple
implied equivalents, as we shall see.)
>>For example, *p++ ...
>There's no associativity involved in this case. Associativity is
only applicable to binary operators.
Well, sort of:

In article <87************@bsb.me.uk>
Ben Bacarisse <be********@bsb.me.ukwrote:
>Associativity (or something very like it) is applicable in expressions
with unary operators if pre- and postfix operators are mixed.
Only if they are given the same "precedence", though.

The problem with a simple precedence grammar is that it does not
tell us what to do when all the operators have the *same* precedence.
In particular, given something like:

x op y op z

does this mean:

op
/ \
(x op y) op z op z
/ \
x y

or does it mean:

op
/ \
x op (y op z) x op
/ \
y z

? It could be either one -- so to "break the tie", we add a
complication to the already-complicated[%] "operator precedence"
grammar, where "precedence" tells us which operator(s) to bind
first[*]. We add "associativity" too; it tells us which operator(s)
to bind first in case "precedence" failed to tell us. It *only*
applies *after* precedence fails, though!
-----
% Yes, complicated: just less-so than the *really* complicated
fully-factored grammar in the C standards.
* Note that this is all about binding operators at *compile*
time. Actual evaluation order at runtime is another matter
entirely.
-----
*p++ could be ((*p)++) or (*(p++))
If we give "++" higher precedence than unary "*", then it can only
be the latter; we need not look for any associativity.

If the standard's grammar is mechanically transformed into an
operator-precedence grammar, the resulting grammar does in fact
give (postfix) "++" higher precedence than unary "*". (It gives
prefix "++" the same precedence, but operators bind to operands,
not to additional operators, so interpreting *++p as (*++)p is
right out.)
>In their operator table K&R list * and ++ as right associative so the
above is interpreted as we all know it is.
Hence, K&R use a *different* grammar -- but one that achieves the
same result.

It is OK to change the grammar if the result is the same. Compiler
writers do this all the time, for various reasons. The C standards
require only that one get the correct answer; the method by which
this "right answer" is obtained is infinitely changeable.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Feb 7 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Mantorok Redgormor | last post by:
Which section(s) in the standard describe associativity rules? e.g., *ptr++ * and ++ are the same precedence wise and as such will be evaluated left-to-right? --
4
by: Chad | last post by:
The following question stems from p.132 in the book "The C Programming Language", second edition by K & R. The have struct { int len; char *str; } *p;
5
by: junky_fellow | last post by:
Hi, I have a very basic doubt about associativity and precedence of operators. I am not a computer science person and may find it quite weird. Consider an expression 4+5*2
2
by: bochengnever | last post by:
( ) and -are left to right in the same order . eg: struct foo { int a ; void * p; } main() { struct foo* A= malloc(sizeof(struct foo));
9
by: marko | last post by:
/* code start */ int a = 0; /* expected evaluation and excution order with precedence in mind /* False(3) , True(1), False(2) */ if ( (a=1) == 0 || 0 != 1 && (a =2) == 1) putchar('T');...
28
by: dspfun | last post by:
I'm trying to get a good understanding of how unary operators work and have some questions about the following test snippets. int *p; ~!&*++p--; It doesn't compile, why? The problem seems to be...
8
by: subramanian100in | last post by:
What does "associativity of operators" mean ? I am unable to undersatand this from K & R 2nd edition. Kindly explain with an example. Thanks
31
by: Jim Langston | last post by:
In Python 2.5 on intel, the statement 2**2**2**2**2 evaluates to 20035299304068464649790723515602557504478254755697514192650169737108940595563114...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.