Проверка, являются ли буферы чередующимся определенным поведением? - PullRequest
0 голосов
/ 22 января 2020

Предположим, мне нужна функция, которая проверяет, чередуются ли два произвольных буфера *. В голову приходит одна простая идея:

bool isInterleaved(uint* buf1, // pointer to first buffer
                   uint* buf2, // pointer to second buffer
                   uint len1,  // length of first buffer
                   uint len2,  // length of second buffer
                   uint stride1, // stride length of first buffer
                   uint stride2) // stride length of second buffer
{
    ... // first some sanity checks like (NULL != buf), (0U < len),...

    bool retval = false;
    if ((len1 == len2) && (2U == stride1) && (2U == stride2))
    {
        if ((&buf1[1] == &buf2[0])  ||
            (&buf2[1] == &buf1[0]))
        {
            retval = true;
        }
    }
    return retval;
}

На бумаге это выглядит достаточно хорошо, быстрые тесты были положительными. Однако В C и C ++ сравнение указателей с объектами строго определено, только если указатели указывают на элементы одного и того же объекта или элементы одного и того же массива.

мой пример - в частности, строка с (&buf1[1] == &buf2[0]) и одна после - представляют собой неопределенное поведение? Если да, как я могу реализовать такую ​​проверку, не полагаясь на неопределенное поведение?


* см. Историю изменений для примера чередующихся данных или посмотрите статью в Википедии о чередовании . Как говорится в комментарии, это не «неправильное слово».

1 Ответ

2 голосов
/ 22 января 2020

Является ли мой пример неопределенным поведением?

Представленный код не имеет неопределенного поведения. Указатели можно сравнить с ==. Даже когда они указывают на разные объекты.

Правило, на которое вы ссылаетесь, применяется к операторам < > <= и >=. Использование этих операторов в «разных объектах» - неопределенное поведение. В проекте стандартной семантики реляционных операторов на указатели можно найти в C99 6.5.8p5 .

...