Допустимо ли псевдоним "const restrict" аргументы указателя?
Если dot_product
объявлен как
float dot_product(const float* restrict a, const float* restrict b, unsigned n);
будет называть это с
dot_product(x, x, x_len)
быть "неопределенным", в соответствии со стандартом C99?
редактировать
x
это указатель, конечно, указывающий на sizeof(float) * x_len
байты памяти, x_len
является unsigned
, Этот вопрос об алиасинге.
3 ответа
У меня нет оригинального текста C99 (то есть ISO9899:1999); У меня есть только копия ISO9899: 2007: TC3. Я ожидаю, что этот текст, взятый со страницы 111 этого документа, очень похож на текст в стандарте C99.
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.
Кажется, это ясно вызывает функции формы, о которой вы спрашивали, как определяющую поведение, при условии, что псевдонимы-указатели используются для доступа только для чтения. Запись через любой из указателей с псевдонимами вызовет неопределенное поведение.
Во-первых, я не думаю, что сам вызов является UB, UB может происходить только внутри функции, если указатели, которые передаются в качестве параметров, используются таким образом, который противоречит спецификации restrict
, (UB не имеет большого смысла для вызова, если это (w/sh) может быть запрещено, это должно было быть сделано с нарушением ограничения, а не UB.)
Затем UB, связанный с restrict
может появиться, только если указанный объект изменен "любым способом". Так что, пока ваши векторы не изменены, все в порядке. Внутри вашей функции это не должно происходить из-за const
квалификация. И если что-то снаружи (скажем, другой поток или обработчик сигнала) изменяет ваши векторы, вы все равно облажались.
Да. Это вызовет неопределенное поведение.
Если restrict
используется ключевое слово и функция объявляется как:
float dot_product(const float* restrict a, const float* restrict b, unsigned n);
тогда компилятор может предположить, что a
а также b
указывать на разные местоположения и обновление одного указателя не повлияет на другие указатели. Программист, а не компилятор, отвечает за то, чтобы указатели не указывали на идентичные местоположения.
Поскольку ваш вызов функции
dot_product(x, x, x_len)
который передает тот же указатель x
к функции, обновляя любой из a
или же b
повлияет на другое вызывающее неопределенное поведение.