Use of parentheses changes how pointer-dereference and increment behaves

Viewed 128

I have this code:

#include <stdio.h>

void f(int* n){
    *n++;
}

int main() {
    int n= 1;
    f(&n);
    printf("%d\n", n);
    return 0;
}

The value of n doesn't change. If I want to change the value of n I must do this:

#include <stdio.h>

void f(int* n){
    (*n)++;
}

int main() {
    int n= 1;
    f(&n);
    printf("%d\n", n);
    return 0;
}

Why are the parentheses so important, and what's the difference between these two lines of code?

*n++;
(*n)++;
3 Answers

This is by design. The precedence of postfix operator ++ is higher than the pointer dereference operator *. And so the compiler will interpret *n++ as *(n++). To change the order in which operators are applied, you must use parentheses.

To be clear about the differences:

  • *n++ increments the pointer, returns the original pointer and dereferences it which results in no change to the integer it points to. It is essentially a "no-op", and any half-decent compiler would optimize your entire function away because it does nothing.
  • (*n)++ dereferences the pointer and increments the integer it was pointing to, which is exactly what you wanted.

You can find a full table here: C Operator Precedence

As always, it usually doesn't hurt to add parentheses tactfully, even if it captures the same ordering as the language specifies. This is a courtesy to anyone reading your code.

Because

void f(int* n){
    *n++;
}

is the same as

void f(int* n){
    n++; // increment of local (stack) variable.
    *n; // reads undefined memory which is foolish but harmless in this instance
}

and is obviously quite pointless (if you'll pardon the pun.)

operator precedence table

(TR)sağdan sola = (EN)from right to left

(TR)soldan sağa = (EN)from left to right

credit: Necati Ergin

For the answer to your question, you should learn the operator priority table. parentheses are at the top of the priority table.

The increment operator and the indirection operator are at the same priority level. But the priority direction is from right to left for this level.

Related