Velocity Reviews > Basic pointers question

# Basic pointers question

Simon
Guest
Posts: n/a

 11-17-2006
I'm trying to understand pointers in a little more detail, and have
written a test program (reproduced below) to experiment with passing
pointers between functions.

Thinking only about the variable x in main, I would expect the
following to happen:
- &x is passed to func_one, so int* p1x is pointing to x (int* p1x =
&x)
- func_one then dereferences p1x to increment x; at this point x = 1
- func_one passes p1x to func_two, so int* p2x = p1x and pointers p2x
and p1x both point to x
- func_two then dereferences p2x to increment x; at this point x = 2
- control passes back to main() and the value of x is printed

Therefore, I would expect this program to produce the output "x = 2; y
= 2; c = 1", but it doesn't. Can anyone provide any insight into why
this is the case?

Simon

--code follows --

#include <stdio.h>

void func_two (int* p2x, int* p2y)
{
*px ++;
*py ++;
}

void func_one (int* p1x, int* p1y, int* p1c)
{
*pc ++;
*px ++;
*py ++;
func_two (px, py);
}

int main (void)
{
int x, y, c, d;
x = y = c = 0;
func_one (&x, &y, &c);
printf("x = %d; y = %d; c = %d", x, y, c);
d = getchar();
return 0;
}

Richard Heathfield
Guest
Posts: n/a

 11-17-2006
Simon said:

> I'm trying to understand pointers in a little more detail, and have
> written a test program (reproduced below) to experiment with passing
> pointers between functions.
>
> Thinking only about the variable x in main, I would expect the
> following to happen:
> - &x is passed to func_one, so int* p1x is pointing to x (int* p1x =
> &x)
> - func_one then dereferences p1x to increment x; at this point x = 1

Here is your mistake. *p1x++ does not increment x (the int pointed to by
p1x)!

This is what happens. Firstly, we need to evaluate p1x++ (because the
grammar says so). The result of this evaluation is the prior value of p1x
(because ++ is POST-increment), and the side effect is to increment p1x at
some time before the next sequence point. The result of the evaluation, as
I say, is the /prior/ value of p1x, which is of course still a pointer to
your original int. The * is then applied to this pointer value, yielding
the value of x, with which you do nothing.

If you want to increment x through p1x, you can do this:

++*p1x;

or this:

(*p1x)++;

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not

Simon
Guest
Posts: n/a

 11-17-2006

Richard Heathfield wrote:
> Here is your mistake. *p1x++ does not increment x (the int pointed to by
> p1x)!
>

Argh!!! - I new it was something simple! I forgot the relative binding
strengths of ++ and *.

Incidentally - there was another mistake in the code above which was
due to me mis-typing it into Google Groups. All now works perfectly -
thanks a lot for your help!

Simon

Chris Dollin
Guest
Posts: n/a

 11-17-2006
Simon wrote:

> I'm trying to understand pointers in a little more detail,

There is hardly any detail to know. Really.

> void func_two (int* p2x, int* p2y)
> {
> *px ++;

Dereference `px` and throw the value away. Increment `px`.

I suspect you meant `(*px)++`, which I would write as
`*px += 1` because I think that makes what's going on clearer.

--
Chris "hantwig efferko VOOM!" Dollin
"- born in the lab under strict supervision -", - Magenta, /Genetesis/

junky_fellow@yahoo.co.in
Guest
Posts: n/a

 11-17-2006

Richard Heathfield wrote:
> Simon said:
>
> This is what happens. Firstly, we need to evaluate p1x++ (because the
> grammar says so). > (*p1x)++;
>

I would request to kindly elaborate on this. I mean to say how from the
C grammar
we can determine this ? In some of the posts, that I read earlier in
this newsgroup
I came to know that C grammar does not specify any precedence. So,
using the C
grammar how post decrement operator is evaluated before the unary
(pointer) operator.
I was looking at the lex and yacc grammar of C, which I downloaded from
the
http://www.lysator.liu.se/c/ANSI-C-grammar-l.html (lex file)
http://www.lysator.liu.se/c/ANSI-C-g...ml#declaration (yacc
file)

Can you please explain how the expression (*p1x++) will be evaluated
using the
lex and yacc files at the above mentioned links ?

thanks a lot for any help in advance ....

Chris Dollin
Guest
Posts: n/a

 11-17-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>
> Richard Heathfield wrote:
>> Simon said:
>>
>> This is what happens. Firstly, we need to evaluate p1x++ (because the
>> grammar says so). > (*p1x)++;
>>

> I would request to kindly elaborate on this. I mean to say how from the
> C grammar we can determine this ?

We look at the productions of the grammar and the meaning of the
constructs.

> In some of the posts, that I read earlier in
> this newsgroup I came to know that C grammar does not specify any precedence.

More accurately, the C grammar does not use the idea of "precedence"
to disambiguate its expression grammar. It just uses an unambiguous
grammar.

In the expression `*p++`, there are only a few productions of interest.
Here is a (strongly selected) view:

primary-expression:
identifier

postfix-expression:
postfix-expression ++
primary-expression

unary-expression:
unary-operator postfix-expression

unary-operator:
*
expression: ... eventually, unary-expression ...

We see from this that `*p++` /must/ be parsed as the unary-operator
`*` applied to the postfix-expression `p++`. There's no other way
to do it (the other productions of the grammar don't help).

> So, using the C grammar how post decrement operator is evaluated
> before the unary (pointer) operator.

The evaluation rules are different from the grammar. The grammar
says how expressions are /structured/. The evaluation rules tell
you how those structures are /evaluated/. They're in the
Standard, but I expect they're not in the gramamr files you

To evaluate `*p++`, we evaluate the unary-expression with operator
`*` and operand `p++`, because that's how it is parsed. To evaluate
`*E`, we evaluate `E` and then dereference the result. Here `E` is
`p++`. To evaluate `X++`, we get the lvalue `X`, deliver its
current value, and note that we must increment `X` by the next
sequence point. So we return the value of `p` (which will be
dereferenced by the `*`) and will eventually increment in. In
the original post, `*p++` is the full expression forming the body
of the expression-statement `*p++;`, which supplies the sequence
point; after the semicolon, `p` will have been incrememented.

--
Chris "hantwig efferko VOOM!" Dollin
"Our future looks secure, but it's all out of our hands"
- Magenta, /Man and Machine/

junky_fellow@yahoo.co.in
Guest
Posts: n/a

 11-17-2006

> In the expression `*p++`, there are only a few productions of interest.
> Here is a (strongly selected) view:
>
> primary-expression:
> identifier
>
> postfix-expression:
> postfix-expression ++
> primary-expression
>
> unary-expression:
> unary-operator postfix-expression
>
> unary-operator:
> *
> expression: ... eventually, unary-expression ...
>
> We see from this that `*p++` /must/ be parsed as the unary-operator
> `*` applied to the postfix-expression `p++`. There's no other way
> to do it (the other productions of the grammar don't help).
>
> > So, using the C grammar how post decrement operator is evaluated
> > before the unary (pointer) operator.The evaluation rules are different from the grammar. The grammar

> says how expressions are /structured/. The evaluation rules tell
> you how those structures are /evaluated/. They're in the
> Standard, but I expect they're not in the gramamr files you
>
> To evaluate `*p++`, we evaluate the unary-expression with operator
> `*` and operand `p++`, because that's how it is parsed. To evaluate
> `*E`, we evaluate `E` and then dereference the result. Here `E` is
> `p++`. To evaluate `X++`, we get the lvalue `X`, deliver its
> current value, and note that we must increment `X` by the next
> sequence point. So we return the value of `p` (which will be
> dereferenced by the `*`) and will eventually increment in. In
> the original post, `*p++` is the full expression forming the body
> of the expression-statement `*p++;`, which supplies the sequence
> point; after the semicolon, `p` will have been incrememented.
>

Thanks Chris for the nice explanation. thanks a lot.