Допустимо ли псевдоним "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 повлияет на другое вызывающее неопределенное поведение.

Другие вопросы по тегам