Is it legal for const aliases to restrict pointer arguments?

If dot_product declared as

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

will call him

 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 smoothing.

+6
source share
3 answers

I do not have the original text C99 (i.e. ISO9899: 1999); I only have a copy of ISO9899: 2007: TC3 . I expect this text, taken from page 111 of this document, to be 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, apparently, explicitly calls the form functions that you asked about as defining behavior, provided that pointers with an alias are used for read-only access. Writing through any of the pointers with an alias will cause undefined behavior.

+6
source

At first, I don’t think that calling UB, UB itself can only occur inside a function if pointers that are passed as parameters are used in a way that contradicts the restrict specification. (UB doesn't make much sense to call, if it's forbidden (w / sh) is forbidden, it should have been a violation of the restriction, not UB.)

Then the UB associated with restrict can appear only if the object with the pointer to the object is changed "in any way." So as long as your vectors are not changed, everything is in order. Inside your function, this should not be due to const qualification. And if something outside (say, another thread or signal handler) changes your vectors, you're screwed up anyway.

+1
source

Yes. It will refer to 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 pointing to different locations, and updating one pointer will not affect the other pointers. The programmer, not the compiler, is responsible for ensuring that pointers do not point to identical locations .

Since your function call

 dot_product(x, x, x_len) 

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

-1
source

All Articles