Почему в g++ 4.9.0 по умолчанию есть std::isnan?

Насколько я понимаю, что функция std::isnan доступно только с C++11 и выше. В дальнейшем, g++ использования -std=gnu++98 если конкретно не сказано не

Так почему же это компилируется?

>> cat test.cpp
#include <cmath>
int main(int argc, char** argv)
{
    return std::isnan(0);
}

>> g++ test.cpp

Есть флаг, чтобы вынуть функцию из <cmath>?

2 ответа

Решение

Это давняя проблема, задокументированная в FAQ, но в которой вы не сможете разобраться.

4,3. _XOPEN_SOURCE а также _GNU_SOURCE всегда определены?

В Solaris g ++ (но не gcc) всегда определяет макрос препроцессора _XOPEN_SOURCE, В GNU/Linux то же самое происходит с _GNU_SOURCE, (Это не полный список; другие макросы и другие платформы также затрагиваются.)

Эти макросы обычно используются в заголовках библиотеки C, защищая новые версии функций от их старых версий. Стандартная библиотека C++98 включает в себя стандартную библиотеку C, но для нее требуется версия C90, которая по причинам обратной совместимости часто не используется по умолчанию для многих поставщиков.

Более того, стандарт C++ требует поведения, которое доступно только на определенных платформах после определения определенных символов. Обычно проблема связана с вводом-выводом typedefs. Для обеспечения корректности компилятор просто предопределяет эти символы.

Обратите внимание, что этого недостаточно #define их только при сборке библиотеки (во время установки). Поскольку у нас нет ключевого слова export, большая часть библиотеки существует в виде заголовков, что означает, что символы также должны быть определены, когда ваши программы анализируются и компилируются.

Чтобы увидеть, какие символы определены, ищите CPLUSPLUS_CPP_SPEC в заголовках конфигурации gcc для вашей цели (и попробуйте изменить их, чтобы увидеть, что происходит при создании сложного кода). Вы также можете запустить g++ -E -dM - [sic], чтобы вывести список предопределенных макросов для любой конкретной установки.

Это обсуждалось в списках рассылки совсем немного.

Этот метод является чем-то вроде бородавки. Мы хотели бы найти более чистое решение, но никто еще не выделил время.

Объяснить:

glibc - это то, что предоставляет стандартную библиотеку C. Поддерживает несколько режимов.

Он поддерживает различные строгие режимы C и строгие режимы POSIX. В этих режимах, когда включены только стандартные заголовки, доступны только стандартные функции. В режиме C90 это не включает isnan,

Он поддерживает различные режимы расширения. В этих режимах также доступны нестандартные функции. В режиме расширений C90 + это включает isnan, _GNU_SOURCE Макрос препроцессора - тот, который включает все расширения.

libstd C++ - это то, что предоставляет стандартную библиотеку C++. Он требует от glibc большего, чем предлагает строгий режим C90. Поэтому есть только два варианта: либо libstd C++ не предлагает те стандартные функции C++, которые он не может предоставить, либо libstd C++ принудительно включает расширения glibc даже в строгом режиме ANSI. Оба означают несоответствие стандарту C++, но первое ограничивает возможности, а второе предоставляет их. Последнее рассматривается как меньшее зло.

Единственный разумный способ исправить это для glibc - предоставить нестандартный способ доступа к своим расширениям даже в строгом режиме ANSI. Такого способа пока не существует, и до его создания нестандартные имена будут доступны даже в стандартных для C++ режимах компиляции.

Разработчикам компиляторов лень точно удалять все функции, которые должны быть доступны только в следующей версии стандарта, особенно если в соответствующих библиотеках (C99) они есть одновременно.

Утилита (для проверки вашего кода на самом деле подчиняется определенному стандарту) недостаточно высока для того, чтобы создатели компилятора чрезвычайно усердно работали над тем, чтобы их компилятор предоставил эту услугу.

Вместо этого обычно происходит реализация новых функций под определенными стандартными флагами. Иногда они случайно переносятся. Когда стандарт завершается, частичная реализация существует некоторое время, пока не станет достаточно хорошей.

Затем начинается работа над следующей версией стандарта. Флаг следующей версии дает вам менее стабильную среду разработки, так как новые функции испытываются, отбрасываются и изменяются.

Некоторое усилие это вложило в то, чтобы не делать бэкпорт-репортажи, но это не шоу-шоппер.

Другие вопросы по тегам