Search code examples
cpointerspointer-arithmetic

Cannot use ++, -- operator on the result from pointer arithmetic


I'm using VS Code and GCC compiler. Here's the code:

#include <stdio.h>
#include <stdlib.h>    

int main()
{
    void *ptr = malloc(100);    

    printf("%p\n", ptr);               
    printf("%p\n", (int *)ptr + 1);    
    printf("%p\n", (int *)ptr - 1);    

    void *ptr2 = ptr; 

    printf("%p\n", (int *)ptr2 + 1);  // Works well

    printf("%p\n", ++(int *)ptr2);    // error: lvalue required as decrement operand



    free(ptr);

    return 0;
}

When I compile the code above, ++(int *)ptr2 gets the error: "lvalue required as decrement operand".

However, (int *)ptr2 + 1 does work. Can anyone explain why this happens?


Solution

  • The result of a cast is not an lvalue. There's a footnote in the 6.5.4 Cast operators section of ISO C11 which states that:

    A cast does not yield an lvalue. Thus, a cast to a qualified type has the same effect as a cast to the unqualified version of the type.

    Similarly, in 6.5.3.1 Prefix increment and decrement operators, it states (my emphasis):

    The operand of the prefix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.

    Hence what you're attempting to do is invalid.

    The reason why (int *)ptr2 + 1 works is because ptr2 is an lvalue so it can be cast. The addition of 1 is done to the cast value and this is also valid.

    The situation you are attempting is no different to something like ++(ptr+1), which is a different way of trying to increment a non-lvalue. It's because both your cast and the expression ptr+1 are ephemeral objects, required to exist only long enough to be used for the immediate operation (the addition or the cast, not the pre-increment).

    Your problem goes away if you slightly re-engineer the way things are done (since void* casts freely to and from most other pointers):

    printf("%p\n", ptr2 = ((int*)ptr2) + 1);