Basic pointers question

Discussion in 'C Programming' started by Simon, Nov 17, 2006.

  1. Simon

    Simon Guest

    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?

    Thanks in advance

    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;
    }
     
    Simon, Nov 17, 2006
    #1
    1. Advertising

  2. 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
    adjust your email clients.
     
    Richard Heathfield, Nov 17, 2006
    #2
    1. Advertising

  3. Simon

    Simon Guest

    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
     
    Simon, Nov 17, 2006
    #3
  4. Simon

    Chris Dollin Guest

    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/
     
    Chris Dollin, Nov 17, 2006
    #4
  5. Simon

    Guest

    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
    following links:
    http://www.lysator.liu.se/c/ANSI-C-grammar-l.html (lex file)
    http://www.lysator.liu.se/c/ANSI-C-grammar-y.html#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 ....
     
    , Nov 17, 2006
    #5
  6. Simon

    Chris Dollin Guest

    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
    downloaded, since they're not part of the grammar.

    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/
     
    Chris Dollin, Nov 17, 2006
    #6
  7. Simon

    Guest


    > 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
    > downloaded, since they're not part of the grammar.
    >
    > 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.
     
    , Nov 17, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeff Bender
    Replies:
    6
    Views:
    349
    Jeff Bender
    Jun 8, 2007
  2. Aarti

    Basic question about pointers

    Aarti, Jul 16, 2007, in forum: C Programming
    Replies:
    13
    Views:
    519
    Bryan Harris
    Jul 17, 2007
  3. Replies:
    6
    Views:
    419
    James Kanze
    Mar 4, 2009
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    696
  5. bpascal123

    c pointers notation basic question

    bpascal123, Mar 16, 2013, in forum: C Programming
    Replies:
    37
    Views:
    575
    88888 Dihedral
    Mar 20, 2013
Loading...

Share This Page