попробуй поймать блоки с бустом

У меня есть функция (член класса), которую я хотел бы избежать сбоя приложения из-за неоднозначности. Для этого я добавил try catch bock, как показано ниже:

void getGene(unsigned int position){
T val;
try {
val =  _genome.at(_isCircular ? position % _genome.size() : position);
}
catch (std::exception& e) {
std::cerr << "Error in [" << __PRETTY_FUNCTION__ << "]: "<< e.what()  << std::endl;
exit(1);
}
return val;
}

Теперь я хочу добавить тестовый модуль Boost, который я подумал сделать что-то вроде

BOOST_AUTO_TEST_CASE(nonCircularGenome_test){

// set size to 10
test.setSize(10);
// set non circular
test.setNonCircular();

// gene at site # 12 does not exist in a 10-site long genome, must throw an exception
BOOST_CHECK_THROW(test.getGene(12), std::out_of_range);

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

Каков наилучший способ заставить обе эти вещи работать так, чтобы пользователю было выдано правильное сообщение об ошибке на ходу, в то время как тесты явно проверяют отладку? Одним из способов является использование # ifdef / # endif DEBUG блоки, но я хочу избежать макросов препроцессора.

Заранее спасибо,

Нихилу

3

Решение

Похоже, вы неправильно понимаете объем и цель исключений — и, возможно, обработки ошибок в целом.

Прежде всего, вы должны определить, каковы предварительные условия вашей функции: делает getGene() всегда ожидай position быть действительным? Ожидает ли это, что его клиенты никогда предоставить неверные позиции?

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

С другой стороны, если ваша функция имеет широкий контракт, то есть она позволяет клиентам передавать любой позиция (даже недействительная) и (a) выдает исключение или (b) возвращает код ошибки, чтобы сообщить об ошибке, когда позиция недействительна, тогда exit(1) линия не должна быть там, потому что вы выходите из программы, и управление не передается обратно вызывающей стороне.

Одна возможность состоит в том, чтобы повторно выдать исключение после регистрации диагностики:

T getGene(unsigned int position){
T val;
try {
val =  _genome.at(_isCircular ? position % _genome.size() : position);
}
catch (std::exception& e) {
std::cerr << "Error in [" << __PRETTY_FUNCTION__ << "]: "<< e.what()  << std::endl;

throw;
//      ^^^^^
}
return val;
}

И если вам не нужно печатать диагностику, просто позвольте распространению исключения:

T getGene(unsigned int position){
return _genome.at(_isCircular ? position % _genome.size() : position);
}
3

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

Других решений пока нет …

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