Я использую анализатор clang, чтобы проверить мой код C ++ на наличие ошибок и ошибок. У меня есть следующая конструкция:
#include <cstdlib>
#include <iostream>
double
somethingThatMayThrow() throw (std::exception)
{
if( rand() % 2 ) {
throw std::exception();
}
return 5.0;
}
int
main()
{
double value = 2.0;
try {
value = somethingThatMayThrow();
} catch( const std::exception& ) {
std::cout << "oops" << std::endl;
}
double someOtherValue = value + 1.0;
std::cout << someOtherValue << std::endl;
return 0;
}
Анализатор теперь жалуется, что начальное значение переменной value
никогда не читается Однако ясно, что значение используется в последней строке тогда и только тогда, когда есть исключение в блоке try. Это понимание правильно, и я смотрю на ошибку в анализаторе? Или я что-то здесь упускаю?
Как стандарт определяет это поведение? Что происходит с левой стороной задания, если правая сторона бросает?
На приведенном ниже снимке экрана показан фактический код, на который жаловался анализатор, который имеет ту же структуру, что и мой пример выше:
Анализатор не так. Вы правы.
Анализатор может быть прав, если код внутри блока try не может выдать std::exception
s или объекты производного от него типа (например, с noexcept
или только с брошенными объектами других типов).
В любом случае, ваша интерпретация верна: назначение никогда не произойдет, если будет выброшена оценка потенциального значения. Таким образом, исходное значение останется без изменений.
Компилятор видит, что вы назначаете someValue
в инициализации value
но потом, внутри try
блок, вы переназначаете его.
И анализатор прав в том случае, когда исключение не выбрасывается, а не в противоположном случае, где value
все равно будет как оригинал someValue
,