6

If dot_product is declared as

float dot_product(const float* restrict a, const float* restrict b, unsigned n);

would calling it with

dot_product(x, x, x_len)

be "undefined", according to the C99 standard?

Edit

x is a pointer, of course, pointing to sizeof(float) * x_len bytes of memory, x_len is unsigned. This question is about aliasing.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
MWB
  • 11,740
  • 6
  • 46
  • 91
  • I don't have the standard to quote, but I have to imagine it's undefined behavior. You're explicitly telling the compiler that no other pointers refer to the same memory location, then violating that hint. I don't think the `const`ness will impact that. – Chris Hayes Dec 18 '13 at 09:21
  • To contradict myself: if `dot_product` is the usual definition of a dot product then I don't think it will *matter*. That is, violating `restrict` should not matter if you only perform read operations on the pointer. It is only when you write that I would expect issues to occur. – Chris Hayes Dec 18 '13 at 09:24
  • Should I remove the "edit"? It seems redundant. I was shocked that **two** people misunderstood my question. – MWB Dec 18 '13 at 09:25
  • @ChrisHayes my question is about the C99 standard rather than "your friendly local compiler", but I agree. – MWB Dec 18 '13 at 09:26
  • To be clear, since `dot_product` seems a very specific example function, is this question about read-only usage of aliased `restrict` pointers? I assume it is, since read-write usage is clearly undefined. – Chris Hayes Dec 18 '13 at 09:33

3 Answers3

6

I do not have the original C99 (that is, ISO9899:1999) text; I only have a copy of ISO9899:2007:TC3. I expect this text, taken from page 111 of that document, is very similar to the text in the C99 standard.

6.7.3.1 Formal definition of restrict

...

10. EXAMPLE 3

The function parameter declarations

    void h(int n, int * restrict p, int * restrict q, int * restrict r)
    {
        int i;
        for (i = 0; i < n; i++)
            p[i] = q[i] + r[i];
    }

illustrate how an unmodified object can be aliased through two restricted
pointers. In particular, if a and b are disjoint arrays, a call of the form
h(100, a, b, b) has defined behavior, because array b is not modified within
function h.

This seems to clearly call out functions of the form you asked about as having defined behavior, provided the aliased pointers are used for read-only access. Writing through either of the aliased pointers would invoke undefined behavior.

Chris Hayes
  • 11,471
  • 4
  • 32
  • 47
1

First I don't think that the call itself is UB, UB can only occur inside the function, if the pointers that are passed as parameters are used in a way that conflicts with the specification of restrict. (UB makes not much sense for the call, if that (w/sh)ould be forbidden, this should have been made a constraint violation and not UB.)

Then, UB related to restrict can only appear, if the pointed to object is modified "in any way". So as long as your vectors aren't modified, everything is fine. Inside your function this shouldn't happen, because of the const qualification. And if something outside (say a different thread or a signal handler) modifies your vectors, you are screwed, anyhow.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
-1

Yes. It will invoke undefined behavior.

If the restrict keyword is used and the function is declared as :

float dot_product(const float* restrict a, const float* restrict b, unsigned n);

then the compiler is allowed to assume that a and b point to different locations and updating one pointer will not affect the other pointers. The programmer, not the compiler, is responsible for ensuring that the pointers do not point to identical locations.

Since your function call is

dot_product(x, x, x_len)  

which is passing the same pointer x to the function, updating any of a or b will affect other causing undefined behavior.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 2
    This doesn't address the `restrict` pointer aliasing question at all. – CB Bailey Dec 18 '13 at 09:19
  • 2
    I downvoted because this is not related to the question in any way. – Chris Hayes Dec 18 '13 at 09:21
  • 3
    There's no issue with `dot_product` updating the pointers independently (it has its own copies of the function parameters). The issue is the pointed-to data. As both parameters are `const` pointers, the question is whether this is still an issue as the function shouldn't be updating the data through either pointer in any case. – CB Bailey Dec 18 '13 at 09:32