Is it legal to alias "const restrict" pointer arguments?
Asked Answered
K

3

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.

Kropp answered 18/12, 2013 at 9:16 Comment(5)
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 constness will impact that.Wendt
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.Wendt
Should I remove the "edit"? It seems redundant. I was shocked that two people misunderstood my question.Kropp
@ChrisHayes my question is about the C99 standard rather than "your friendly local compiler", but I agree.Kropp
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.Wendt
W
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.

Wendt answered 18/12, 2013 at 9:45 Comment(0)
W
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.

Workbench answered 18/12, 2013 at 9:51 Comment(0)
T
-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.

Thompson answered 18/12, 2013 at 9:17 Comment(3)
This doesn't address the restrict pointer aliasing question at all.Assess
I downvoted because this is not related to the question in any way.Wendt
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.Assess

© 2022 - 2024 — McMap. All rights reserved.