#gcc #floating-point #c99 #built-in #isnan
Вопрос:
В описании встроенных модулей GCC говорится::
GCC предоставляет встроенные версии макросов сравнения ISO C99 с плавающей запятой, которые позволяют избежать возникновения исключений для неупорядоченных операндов. Они имеют те же имена, что и стандартные макросы ( isgreater, isgreaterequal, isless, islessequal, islessgreater и isunordered) , с префиксом _buildin. Мы хотим, чтобы разработчик библиотеки мог просто #определить каждый стандартный макрос в соответствии с его встроенным эквивалентом. Таким же образом GCC предоставляет встроенные модули fpclassify, isfinite, isinf_sign, isnormal и signbit, используемые с префиксом _buildin. Встроенные функции isinf и isnan отображаются как с префиксом _buildin, так и без него.
Итак, я не совсем в состоянии разобрать это. Когда сравнения с плавающей запятой должны вызывать исключения? Выполняет ли стандарт C мандат, который они выполняют? А они этого не делают? Ничего не предписывает? И — __builtin_isnan()
действует ли иначе, чем isnan()
?
Ответ №1:
По исключению здесь документы GCC ссылаются на исключения IEEE 754 с плавающей запятой. Если вы сделаете что-то вроде
a < b
и одним из операндов является NaN, будет вызвано исключение FP (недопустимое). Это означает, что бит в FPU будет оставаться установленным до тех пор, пока он явно не будет очищен программистом. Используя вместо isgreater
этого / isless
/и т. Д., программист может избежать запуска исключения FP.
Комментарии:
1. Итак, текст «исключение» относится только к LT/GT/LTE/GTE, а не к чему-либо еще? т. е. не isnan ?
2. Да, моя интерпретация текста, который вы процитировали, заключается в том, что GCC предоставляет другие встроенные модули, чтобы стандартные реализации библиотек могли их использовать, и часть исключения применяется только к сравнениям.
3. Интерпретация-это хорошо, но… Я хочу знать это наверняка.
4. Если вам нужно что-то более авторитетное, чем документы, я предлагаю вам написать несколько небольших тестовых программ и посмотреть, как они себя ведут и какой ASM они генерируют, или посмотреть исходные тексты компилятора (я бы предположил, что первым местом для поиска будет поиск встроенного IN_ISNAN в gcc/встроенных.c).
5. Хорошая идея. Я совершил ошибку, пытаясь найти isnan() в источниках glibc, и подагра обескуражила 🙁