C ввел концепцию единого errno
или «номера ошибки», который можно использовать для определения точной причины отказа некоторых стандартных функций, включая математические функции, при выполнении своих обязанностей.POSIX расширила errno
, и C ++ 11 также выбрал некоторые из этих расширений.
Когда одна из этих функций не работает, глобальному целому числу errno
присваивается значение, которое говорит вам, почему.Очевидно, это влечет за собой снижение производительности.
GCC говорит, что этот флаг отключает это поведение для определенных математических функций, ускоряя вашу программу за счет диагностической утилиты и соответствия стандартам.
Если вы уже не наблюдаете errno
, когда происходит сбой какой-либо из затронутых функций, и, вероятно, нет, потому что вы никогда о ней не слышали, тогда вы не потеряете никакой функциональности.Это может быть в том случае, если вы пишете действительно ограниченную во времени программу или когда конкретная причина сбоя не диктует, что ваш код будет делать дальше.(Тем не менее, я советую более подробно изучить проверку ошибок, чтобы убедиться, что ваш код является настолько надежным, насколько это должно быть.)
Однако вы можете случайно наблюдать побочные эффекты, если у вас естьЖук.Представьте, что вы делаете что-то вроде следующего:
std::some_maths_function(42);
if (errno == ERANGE)
exit(-1);
Упс!Мы проверяем errno
, даже когда some_maths_function(42)
удалось.Предположим, что над этим кодом находится вызов std::some_other_maths_function(999)
, который обычно завершается неудачно и в результате errno
устанавливается на EDOM
.Это скрывало ошибку в приведенном выше коде.
Теперь включите флаг компилятора.Если some_other_maths_function
является одной из функций, которые больше не устанавливают errno
, ваша ошибка будет снята, и вам может потребоваться несколько минут, чтобы понять, что вы должны написать что-то вроде:
if (std::some_maths_function(42) == -1)
{
if (errno == RANGE)
exit(-1);
}
Конечно, вряд ли GCC виноват в том, что у вас была ошибка, но это действительно показывает, как поведение вашей программы может отличаться после включения этого флага «оптимизации».Действительно, документация гласит:
Эта опция не включена ни одним параметром -O, так как это может привести к неправильному выводу для программ, которые зависят от точной реализации IEEE илиПравила / спецификации ISO для математических функций.Однако это может привести к более быстрому коду для программ, которые не требуют гарантий этих спецификаций.
Другими словами, этот флаг отправляет вас за пределы книги.Но, возможно, оно того стоит.
Переменная errno
должна быть локальной для потока (то есть на самом деле это одна из них для каждого потока в вашей программе), иначе она будет бесполезна вмногопоточная программа.Вы можете изучить термин "локальный поток" для получения дополнительной информации по этому вопросу.