void main()
unsigned short Result = Add(12345, 54321);
if (ErrorCode == -1)
cout « "Переполнение!\n";
else
cout « "Ответ равен " « Result « "\n";
}
Этот способ неплох в своем роде, но также не свободен от серьезных проблем. Как и в двух предыдущих случаях, программист, имеющий дело с этой функцией, точно так же должен помнить определенные коды ошибок и точно так же не должен забывать о проверке переменной ошибки после вызова функции.
Кроме того, существенным недостатком этой стратегии является ее зависимость от глобальных данных. Последующие обращения к другим функциям могут без уведомления изменить переменную ошибки прежде, чем она будет обработана. Проблема обостряется при работе под операционными системами типа Windows 95 и Windows NT, поддерживающими многопотоковый (multithreaded) режим. В этом случае переменная ошибки может измениться даже прежде, чем у программы вообще появится шанс проверить ее значение.
Использование глобальных переменных для кодов ошибок имеет долгую традицию, восходящую к ранней поре процэаммирования на С под управлением операционной системы UNIX. Переменная errno используется по сей день, хотя большинство поставщиков компиляторов поддерживает errno больше ради совместимости, чем как серьезный механизм сообщения об ошибках.
Использование оператора goto или пары функций setjmp/longjmp.
Как goto, так и setjmp/longjmp прерывают нормальный ход выполнения программы, поэтому стратегию обработки ошибок, основанную на одном из этих подходов, нельзя проигнорировать. Подобная стратегия обеспечивает гарантию того, что возможные серьезные ошибки не проскользнут незамеченными. С другой стороны, применение обоих этих методов сталкивается с серьезными трудностями при работе с объектами C++.
Сначала рассмотрим оператор goto. Листинг 22.3 демонстрирует, как можно перехватывать ошибки при помощи этого оператора.
unsigned long sum = addendl + addend2;
if (sam > USHRT_MAX)
goto OverflowError;
sout « "Сумма равна " « sum « "\n";