454,599 Members | 1,184 Online
Need help? Post your question and get tips & solutions from a community of 454,599 IT Pros & Developers. It's quick & easy.

# Basic pointers question

 P: n/a 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 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; } Nov 17 '06 #1
6 Replies

 P: n/a 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. Nov 17 '06 #2

 P: n/a 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 Nov 17 '06 #3

 P: n/a 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/ Nov 17 '06 #4

 P: n/a 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-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 .... Nov 17 '06 #5

 P: n/a ju**********@yahoo.co.in wrote: > Richard Heathfield wrote: >Simon said:This is what happens. Firstly, we need to evaluate p1x++ (because thegrammar 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/ Nov 17 '06 #6

 P: n/a 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 '06 #7

### This discussion thread is closed

Replies have been disabled for this discussion.