3

Say I have a function that takes 2 non-aliased int*, and copies one int into the other, then returns the int* that served as the destination. For example:

int* copy_int(int* restrict dest, int const* restrict src) {
    *dest = *src;
    return dest;
}

Is any of the following calling code undefined behaviour?

void caller(void) {
    int dest;
    int src = 42;

    copy_int(&dest, &src);  // ignored return value aliases &dest
}
void caller(void) {
    int dest;
    int src = 42;

    int* dest_addr = copy_int(&dest, &src);  // dest_addr aliases &dest
}
void caller(void) {
    int dest;
    int src = 42;

    int* dest_addr = &dest;
    int* dest_addr_2 = copy_int(&dest, &src);  // dest_addr_2 aliases dest_addr
}

Or am I safe to assume that restrict only applies inside the callee, and that I can alias those pointers outside the function call?

  • 3
    FWIW, the formal definition of `restrict` is in section 6.7.3.1 of the C standard. Another point of interest is that your `copy_int` function has a similar signature, and the same return behavior (returning the destination pointer) as the standard library function `memcpy`. I've never heard of any limits on the use of the return value from `memcpy`. – user3386109 Apr 13 '20 at 19:14
  • @user3386109 yes, it is simillar. On that note, why doesn't `memcpy` have restrict qualifier on its parameters? The documentation states that the memory areas must not overlap, which is even a stricter requirement. – no_stupid_questions Apr 15 '20 at 02:24
  • 1
    The signature of `memcpy` per section 7.24.2.1 of the C11 specification is `void *memcpy(void * restrict s1, const void * restrict s2, size_t n);` Which is to say that it *does* have the restrict qualifier on its parameters. – user3386109 Apr 15 '20 at 02:36
  • You're right, I just checked the standard. My pc's man pages aren't accurate, strange. Maybe because it wasn't restrict qualified up until C99? – no_stupid_questions Apr 15 '20 at 02:41
  • @no_stupid_questions The next release of the man pages will add `restrict` to the prototypes of functions that use it. It was recently added in a patch set of mine. – alx - recommends codidact Sep 05 '22 at 23:40

1 Answers1

2

restrict applies to inside copy_int(int* restrict dest, int const* restrict src) in what the function can assume - leading to better optimized code. The caller is obliged to pass addresses that do not overlap data.

All cases do the same thing in that regard: copy_int(&dest, &src);. dest and src are not aliasing each other. The aliasing cases presented by OP do not affect dest, src.

Example of bad code below.

copy_int(&src, &src);  // bad
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256