Когда справедливо целенаправленно вызывать неопределенное поведение?

Стандартная библиотека обычно допускает неопределенное поведение, если вы нарушаете какие-либо требования к типам шаблонов, приводите ошибочные аргументы функций или любое другое нарушение договора. Считается ли хорошей практикой разрешать это в пользовательских библиотеках? Когда это справедливо?

Подумайте о написании operator[] для контейнера:

template <typename t>
T& container<T>::operator[](int i)
{
return internal_array[i];
}

Если i индексы за пределами internal_arrayмы столкнулись с неопределенным поведением. Должны ли мы допустить это или выполнить проверку границ и создать исключение?

Другим примером является функция, которая принимает int аргумент, но разрешает только ограниченный домен:

int foo(int x)
{
if (x > 0 && x <= 10) {
return x;
}
}

Если x не находится в домене, выполнение достигнет конца функции без return утверждение — это дает неопределенное поведение.

Должен ли разработчик библиотеки чувствовать себя плохо из-за этого или нет?

3

Решение

Когда справедливо целенаправленно вызывать неопределенное поведение?

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

Стандартная библиотека C ++ 11 определяет множество таких функций: просто подумайте об операторе индекса для коллекций последовательностей.

Если вы спрашиваете об этом с точки зрения разработчика приложений, с другой стороны, ответ, конечно, «никогда», если вы пишете непереносимый код, который опирается на некоторые документированный расширение вашего компилятора и / или на некоторые функциональные возможности вашей операционной системы (но тогда можно поспорить, все еще ли вы «говорите на C ++»).

Должен ли разработчик библиотеки чувствовать себя плохо из-за этого или нет?

Если бы это было так, мистер. Степанов должен чувствовать какой ужас к настоящему времени Нет, это не плохо, это просто зависит от того, разработана ли ваша библиотека для максимальной эффективности или для максимальной безопасности — с большим количеством нюансов в середине.

3

Другие решения

Все сводится к документации.

Интуитивно вы не ожидаете [] сделать любую обязательную проверку, но вы также можете предоставить at метод для вашего контейнера, который выдает исключение (да, точно так же, как люди, которые пишут std). Конечно, вы можете выдать исключение, но задокументируйте это поведение.

Второй — это честный ход, если вы четко задокументируете, что поведение не определено, если функция вызывается с неверными аргументами. а также у вас есть веская причина для этого (красный). Если вы разрабатываете библиотеку, критичную к производительности, вам не нужны накладные расходы на проверку ввода. Если нет, бросьте исключение.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector