Search code examples
cpointerslanguage-lawyersequence-points

Passing pointers to the same address as function arguments


Suppose I have a weired add function which does an addition and an increment then stores the result to somewhere else.

void add(const int* a, const int* b, int* c) {
    *c = (*a)++ + *b;
}

If I pass the same pointer to a and c,

int a = 1, b = 3;
add(&a, &b, &a);

Then it will eventually modify the value pointed by a.

My questions:

  1. Does this violate the const qualifier for the first argument?
  2. Is the operation undefined as the typical unsequenced x = x++ is?

I feel the answer to both questions should be YES, but my gcc gives a warning for neither.

EDIT: I know there can be a better workaround for the sake of the code. My question is more on the language feature itself.


Solution

  • You have

    void add(const int* a, const int* b, int* c) {
        *c = (*a)++ + *b;
    }
    

    This doesn't compile.

    <source>:2:14: error: increment of read-only location '*a'
        2 |     *c = (*a)++ + *b;
          |      
    

    We could remove the const.

    void add(int* a, const int* b, int* c) {
        *c = (*a)++ + *b;
    }
    

    But then we encounter undefined behaviour when a == c || a == b. We can signal this using the restrict keyword.

    void add(int* restrict a, const int* restrict b, int* restrict c) {
        *c = (*a)++ + *b;
    }
    

    With this signature, it becomes UB to call add with two identical arguments.