# Thread: difference between ++*x and x*++

1. ## difference between ++*x and x*++

i forget when it was but recently i asked about why x++ generated a warning but *x += 1 doesn't it was explained to me that the ++ operator has higher precedence than the * (or the other way round, i just made a mental note not to do it in general) so by writing *x++ you were incrementing the pointer by 1 not the value it pointed to. however i have just typed out a program in the c unleashed book using an array of functions to play with it and in each function the author writes ++*x (as an example) i thought to myself ah-ha this isn't going to work but it did. as an experiement i changed all the ++*const to *const++ and sure enough i got the warning i expected in the first place.

as far as i understand it ++x increments x before using it and x++ increments x sometime after using it but before the line of code is finished executing (hence the use of x++ in for loops and the such).

question arises then is why does ++*x increment the value that *x is pointing to and *x++ increments the pointer *x

2. Originally Posted by cooper1200
question arises then is why does ++*x increment the value that *x is pointing to and *x++ increments the pointer *x
It's a matter of syntax. In ++*x the syntax is such that there's no way to interpret the increment as applying to x rather than *x, hence it is equivalent to ++(*x). In *x++ there are two possible interpretations: (*x)++ vs *(x++), and precedence rules say that the latter is the correct interpretation of the syntax, hence the increment applies to x, not *x.

By the way, don't say "the pointer *x" unless you mean that *x is itself of a pointer type. If you want to refer to x as being the pointer, say "the pointer x". Likewise, "the value that *x is pointing to" means that *x is a pointer and you're talking about **x. Rather, say "the value that x is pointing to", or just say *x.

3. ok suppose x is a pointer to an array element and for some reason i want to point at the next element before i use the value that x is pointing to would i have to write two lines of code ie
Code:
```*x++;
//now do something with it```
or could i write ++(*x)
coop

4. Code:
```#include <stdio.h>

int main(void)
{
int numbers[] = {0, 1, 2};

{
// Option #1
int *x = numbers;
++x;
printf("%d\n", *x);
}

{
// Option #2
int *x = numbers;
x++;
printf("%d\n", *x);
}

{
// Option #3
int *x = numbers;
printf("%d\n", *++x);
}

{
// Option #4
int *x = numbers;
printf("%d\n", *(++x));
}
}```

5. @cooper1200,

What laserlight pointed out is that the statement is ambiguous to human eyes. It should not be used without parenthesis because of it.

Where int * x; is the type:

If you intend to increment the pointer, be clear always with *(x++) or *(++x), and if you want to increment the integer it points to be clear by explicating it with (*x)++. This way you and everyone else has less question as to your intent without reviewing the operator precedence rules.

However, it is worse than just this. There are no absolute guarantees about when the increment is performed, which means optimization settings can change the order of things. This means it's not unambiguous to combine increments with other operations, and a de-reference is a separate operation from the increment in these clauses, so:

int z = ++i + ++i;

v[i] = ++i;
v[++i] = i;
can't really be relied upon, every time, for the order in which these increments are actually performed. It may be shorter to write these clauses, but various formations of this kind of writing can be quite tricky to recognize as a bug, especially where it works as expected in debug mode but fails in release mode (due to optimizations changing the order of events).

The basic notion for coding standards is to use ++, pre and post, in isolation (separated by statements). It may be more "longhand", but it makes the code more obvious and can eliminate undefined order of evaluation issues.

For example, in the last clause of a typical for loop, you'll often find: for( int n=0; n < x; ++n ). In this case, n is incremented in isolation. There's no ambiguity about when the increment will be performed.

Stroustrup puts it this way (I paraphrase): The order of evaluation of sub-expressions is designed for the optimizer rather than the programmer. One should avoid complicated expressions wherever possible to be clear. A simple rule which ends these problems is: do not read or write to a value twice in the same expression.

That's exactly what *(x++) or (*x)++ does, it writes (increments) and reads (dereferences) upon the same pointer twice in one clause. It's actually a bad habit, because to use this, one needs something like a = *(x++), which should work just fine, but if you THEN make it a = *(x) * *(x++), there may be no guarantee left as to WHEN the increment will be performed under all configurations of the compiler.

Another point students don't quite realize happens with ++ (especially post, like n++) is applied to a class instantiation. This implies a copy is to be made for the increment. Optimizers should skip that, but there may be performance implications using post increment in all cases where it doesn't matter. When it doesn't matter, the habit should be pre, not post increment.

6. Originally Posted by Niccolo
but if you THEN make it a = *(x) * *(x++), there may be no guarantee left as to WHEN the increment will be performed under all configurations of the compiler.
It is guaranteed that the behaviour is undefined.

Originally Posted by Niccolo
Another point students don't quite realize happens with ++ (especially post, like n++) is applied to a class instantiation. This implies a copy is to be made for the increment. Optimizers should skip that, but there may be performance implications using post increment in all cases where it doesn't matter. When it doesn't matter, the habit should be pre, not post increment.
This is the C programming forum, so this consideration is not relevant.

7. Originally Posted by cooper1200
question arises then is why does ++*x increment the value that *x is pointing to and *x++ increments the pointer *x
In another question we told you about precedence and associativity of expressions. laserlight draws my attention to my confusion about "evaluation" and "grouping", and she's right (just remember, I am not a native english speaker - my examples showed the grouping!)...

The fact is, in every expression you must deal with precedence and associativity. Taking *x++ as example, the post-increment operator ++ has precedence over * indirection operator, so the compiler will separate these operations as *(x++). Taking ++*x as example, the pre-increment operator has the same precedence of the * indirection operator... Here comes the associativity: both operator have right to left associativity, so the expression is ++(*x).

Take a look in another classic example... Supose you have a simple structure:
Code:
```struct s { int *xp; } s, *p;
int a = 1;
s.xp = &a;
p = &s;```
What pointer is being derreferenced, if you do this?
Code:
`int y = *p.x;`
Here, the access member operador (.) has precedence over the indirection operator *, so the expression is:
Code:
`int y = *(p.x);`
If you want to a derreference to the p pointer you must do:
Code:
`int *yp = (*p).x;`
That's why in the late 80's, the ANSI comitee extended C language adding the -> operator (with the same precedence as the (.) operadtor). To avoid the use of parentesis and the confusion you can write:
Code:
`int y = *p->x;`
Here, '->' has precedence over * and you are derreferencing the x member, not p.

So, always pay attention to precedence and associativity. They are important!

8. Maybe its just me,but singlestep some code in debugger makes me understand how the code and machine works better than human explaining

9. That's not wrong, but when you run into the kind of undefined behaviour that Niccolo mentioned, it won't help you.

10. when who runs into undefined behaviour?

11. Anyone who uses expressions with such side effects in complex expressions.

12. @cooper1200, @laserlight's point is demonstrated most clearly by experience where the debugger shows in one configuration that such code might work as you expect, but then a change in configuration breaks it.

All of us this side of a few years' experience see it happen, followed by a facepalm.

13. Originally Posted by Niccolo
@cooper1200, @laserlight's point is demonstrated most clearly by experience where the debugger shows in one configuration that such code might work as you expect, but then a change in configuration breaks it.

All of us this side of a few years' experience see it happen, followed by a facepalm.
you wrote about optimization,so I seen some compilers optimize to hard to follow and one exotic optimize to branchless code,like you mean full optimize arent foolproof,it suddenly breaks code,moving increments ????

14. It is true that compiler can have bugs concerning optimisation, especially at high optimisation levels. However, examples like ++i + ++i are bugs with the program, not the compiler. They just happen to commonly manifest when compiler configuration such as optimisation levels change, but even if the bug doesn't manifest, it's still there. Maybe a compiler upgrade will break the code, etc.

15. Stay away from undefined behaviour.

I'd also caution the use of implementation defined behaviour...

I've been caught before when work changed from one compiler to another.

Everything that wasn't portable needed to be redone... It was a bad time...

Now days I put a lot of emphasis on code being portable - And if it can't be portable, calling it from an external source so that it can be changed more easily - Utilizing an "Interface"