Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: pointer arithmetic question. |
| Date | 2012-05-06 06:58 +0000 |
| Organization | Aioe.org NNTP Server |
| Message-ID | <20120505232451.950@kylheku.com> (permalink) |
| References | <8d75171a-27cf-45ac-b9f4-57427d79b0d6@h4g2000pbe.googlegroups.com> |
On 2012-05-06, somenath <somenathpal@gmail.com> wrote:
> *t = toupper(*t++);
Since t is modified in this expression, its value may not simultaneously be
used for purpose other than determining the new value being stored into t.
Here, t is also used to compute the storage location where to put the
result of toupper.
This use is not divided from the t++ modification by a sequence point.
> *t = toupper(*t++);
> The = operator has associativity
*GONG*
Associativity is how you parse the symbols to make a parse
tree. Evaluation is tree walking. A tree can be walked in many orders.
In C, the tree of an expression, so to speak, may be evaluated in any possible
order, subject to only sequence points, which are basically assertions that one
subtree must be done before another.
Once you use "associativity" or "predecence" in describing what you
think the evaluation order should be, you've basically lost.
> from right to left so toupper(*t++); will be evaluated first the the
No, we have this tree
=
/ \
* call()
/ / \
t toupper args
/
*
/
++(post)
/
t
The only sequence point in this expression tree is before the function call.
That is, once toupper is evaluated to a function pointer, and once the args are
evaluated, and the function is ready to be called, a sequence point takes
place, and then the function is invoked.
Furthermore, to complicate things, the completion of side effects can take
place out of order with respect to the tree. Side effects can be gathered into
a "queue" and then "flushed" at the next sequence point.
However, this is played out in the right subtree of the main = node.
It has no bearing on when the left side of the = is evaluated.
(Of course, when the function is being called, the evaluation of this tree is
suspended!)
For instance, here is a possible order:
= 9
/ \
*8 call() 7
/ / \
t toupper args
1 4 /
* 5
/
++(post) 3,6
/
t
2
I put 3,6 next to the ++ because it has two events: computation of its value in
the expression tree (the value yielded by ++, which is the prior value of t),
and the event of updating t to the new value: the completion of the side
effect.
In my order above, I gave it #6: the increment happens just before 7, the call to the function (which is preceded by a sequence point). This update cannot
be delayed past the function call.
You also have to keep in mind that parallel orders are possible, and there
is optimization. Both 1 and 2 just access t so they can be merged.
Note how in my order, the dereference on the left happens at point 8,
after the function call. But the value of t accessed for that purpose happens
at point 1. So it's the old value of t.
Here is a different possible order:
= 9
/ \
*8 call() 7
/ / \
t toupper args
5 1 /
* 6
/
++(post) 3,4
/
t
2
Note this sneaky evaluation order. The t++ is evaluated early (steps 2, 3, 4),
and to completion (4 means the side effect completes and t is updated).
The very next step is 5, which is the evaluation of t in the left hand side.
It now fetches the new value!
Then evaluation goes back to the right side and completes the function call.
The result of the call is assigned to the new location pointed at by the new t,
not the old location.
In all orders, the = will be 9, because = is the root, and so it is visited
last. The evaluation of the tree cannot be just be any order whatsoever. It
has to be a bottom-up traversal! But many bottom-up traversals are possible.
Precedence and associativity are related to evaluation order like this.
They establish what is bottom and what is up. For instance,
a + b * c gives us this tree:
+
/ \
a *
/ \
b c
In all possible traversals, the * node is visited before the + node.
However, the a, b and c nodes can be visited in any six possible orders.
They are all bottom nodes (leaf nodes) and we can pick any bottom node to be
evaluated first.
The constraints are: * cannot be evaluated before b and c. (You can't multiply
until you have the values of the multiplicands!) And + cannot happen until the
* is done, and the value of b is known (you can't add until you have the
two terms.)
Yet, six serial evaluation orders are possible, plus parallel evaluation.
--
If you ever need any coding done, I'm your goto man!
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
pointer arithmetic question. somenath <somenathpal@gmail.com> - 2012-05-05 21:46 -0700
Re: pointer arithmetic question. Philip Lantz <prl@canterey.us> - 2012-05-05 23:25 -0700
Re: pointer arithmetic question. Paul N <gw7rib@aol.com> - 2012-05-06 07:52 -0700
Re: pointer arithmetic question. Kaz Kylheku <kaz@kylheku.com> - 2012-05-06 06:58 +0000
Re: pointer arithmetic question. pete <pfiland@mindspring.com> - 2012-05-06 08:53 -0400
Re: pointer arithmetic question. pete <pfiland@mindspring.com> - 2012-05-08 06:35 -0400
Re: pointer arithmetic question. Tim Rentsch <txr@alumni.caltech.edu> - 2012-05-08 06:37 -0700
Re: pointer arithmetic question. Kaz Kylheku <kaz@kylheku.com> - 2012-05-08 14:32 +0000
Re: pointer arithmetic question. Tim Rentsch <txr@alumni.caltech.edu> - 2012-05-08 10:31 -0700
Re: pointer arithmetic question. Kaz Kylheku <kaz@kylheku.com> - 2012-05-09 21:04 +0000
Re: pointer arithmetic question. Tim Rentsch <txr@alumni.caltech.edu> - 2012-05-10 10:06 -0700
Re: pointer arithmetic question. Kaz Kylheku <kaz@kylheku.com> - 2012-05-11 17:52 +0000
Re: pointer arithmetic question. Tim Rentsch <txr@alumni.caltech.edu> - 2012-05-11 19:27 -0700
csiph-web