Многие ресурсы inte rnet требуют проверки предварительных условий в функциях API с помощью if (something_is_wrong) throw Exception{}
вместо assert(!something_is_wrong)
, и я вижу в этом некоторые хорошие моменты. Тем не менее, я боюсь, что такое использование может привести к удвоению тех же проверок:
void foo(int positive) {
if (positive < 1) {
throw std::invalid_argument("param1 must be positive");
}
}
void caller() {
int number = get_number_somehow();
if (number >= 1) {
foo(number);
}
}
, вероятно, будет выполняться как
int number = get_number_somehow();
if (number >= 1) {
if (number < 1) {
throw std::invalid_argument("param must be positive");
}
}
, если вызов не будет встроен и оптимизирован путем вырезания один из if
с, я думаю. Кроме того, написание чека дважды (в foo()
и в caller()
) может нарушать правило DRY. Поэтому, возможно, мне следует go, чтобы
void caller() {
int number = get_number_somehow();
try {
foo(number);
} catch (std::invalid_argument const&) {
// handle or whatever
}
}
, чтобы избежать повторения этих проверок предварительных условий, обеспечивая небольшую производительность и большую ремонтопригодность в случае изменения контракта функции.
Однако я не всегда могу применить такие логи c. Представьте, что std::vector
имеет только at()
, но не operator[]
:
for (int i = 0; i < vector.size(); ++i) {
bar(vector.at(i)); // each index is checked twice: by the loop and by at()
}
Этот код приводит к дополнительным проверкам O (N)! Не слишком ли это много? Даже если он оптимизирован так же, как описано выше, как насчет ситуаций с косвенными вызовами или длинными функциями, которые, вероятно, не будут встроены?
Итак, должна ли моя программа быть написана в соответствии с правилами ниже?
- , если функция API, вероятно, не будет встроенной или ожидается многократный вызов с проверками на сайте вызова (см. Пример
vector
), assert()
ее предварительные условия ( внутри него); - функции броска try-catch вместо проверки их предварительных условий перед вызовом (последний, кажется, прерывается DRY).
Если нет, то почему?