Идеология Qt относительно проверки значений

317
02 декабря 2017, 09:51

Начну с примера. Есть такая функция mid() для контейнерных классов, в частности для QVector. Она позволяет получить вырезку из середины контейнера. В описании функции значится следующее:

Returns a sub-vector which contains elements from this vector, starting at position pos. If length is -1 (the default), all elements after pos are included; otherwise length elements (or all remaining elements if there are less than length elements) are included.

Для длины указано одно специальное значение -1, так же сказано, что если length больше реального хвоста, то будут взяты все оставшиеся элементы. Что же произойдёт, если позиция будет отрицательной или превышающей реальный размер контейнера, а также при других отличных от -1 отрицательных значения длины - не понятно. Приходится лезть в исходники и смотреть самому:

QContainerImplHelper::CutResult QContainerImplHelper::mid(int originalLength, int *_position, int *_length)
{
    int &position = *_position;
    int &length = *_length;
    if (position > originalLength)
        return Null;
    if (position < 0) {
        if (length < 0 || length + position >= originalLength)
            return Full;
        if (length + position <= 0)
            return Null;
        length += position;
        position = 0;
    } else if (uint(length) > uint(originalLength - position)) {
        length = originalLength - position;
    }
    if (position == 0 && length == originalLength)
        return Full;
    return length > 0 ? Subset : Empty;
}

Здесь уже обработаны все ситуации и поэтому реального выхода за границы массива, и как следствие UB, мы получить вроде бы не должны. Но почему же этого не указано в "верхнем" описании функции в справочном центре? Может быть предполагается, что для каких-то "особо оптимизированных" случаев этих проверок не будет? Или Qt это в первую очередь максимальная защита от дурака?

Пока же получается, что если человек приходит в мир Qt из чистого C++ он будет довешивать дополнительные проверки аргументов перед вызовом, дабы не словить UB, хотя эти проверки уже есть внутри библиотеки. Таким образом тратя время на ненужный код. А тот, кто наоборот, начинал с Qt при переходе в чистый C++ получит по полной программе всевозможных Access Violation в рантайме.

В итоге, хочется понять, чем же всё таки руководствоваться при разработке кода, используя библиотеку Qt. Можно ли полагаться на максимальную безопасность и проверку параметров всегда и везде или всё же кое-где стоит обеспечивать ручную проверку, т.к. справка не содержит достаточной информации?

Answer 1

На мой взгляд, в работе с Qt, как и с другими библиотеками, необходимо соблюдать контракт. То есть соответствие параметров вызовов и интерпретации возвращаемых значений тому, что написано в хелпе (или документировано еще как-то). Ибо то, что не указано в контракте, может быть изменено. При переходе, скажем, на другую версию библиотеки.

К тому же, нарушение контракта часто может свидетельствовать не о том, что вы знаете и используете "недокументированные возможности", а о наличии ошибки в вашей логике. А это осложняет сопровождение такого кода.

READ ALSO
QTcpServer::write() - не отправляются пакеты

QTcpServer::write() - не отправляются пакеты

Есть следующий код маленького сервачка:

340
Работа с матрицами (двумерные массивы) С++

Работа с матрицами (двумерные массивы) С++

Помогите с кодом, пожалуйста

447
wstring проблема с кириллицей

wstring проблема с кириллицей

Функция принимает на вход две части кода кириллицы (2 байта)Нужно преобразовать их в русский текст

291
Удаление элемента из списка по значению переменной [требует правки]

Удаление элемента из списка по значению переменной [требует правки]

Как написать удаление элемента односвязного списка, если этот элемент - это значение переменной другого класса?

494