C имеет __STDC__
, но, похоже, не существует стандартного способа распознавания некоторых расширенных диалектов C++. Следовательно, для переносимого кода я использую
#define __is_extended \
((__GNUG__ &&!__STRICT_ANSI__) || \
(_MSC_VER && _MSC_EXTENSIONS && __cplusplus) || \
(__IBMCPP__ && __EXTENDED__))
Пока это работает для gcc, XLC и Visual C++.
Мы должны тестировать соответствие ISO/ANSI идиосинкразически для каждого компилятора, верно? Если да, можете ли вы предложить другие компиляторы, которые доказали свою эффективность?
РЕДАКТИРОВАТЬ: Поскольку было так много дискуссий о «за» и «против» таких тестов, вот реальный пример. Скажем, есть некоторый заголовок stuff.h, широко используемый несколькими компиляторами в нескольких проектах. stuff.h использует некоторые специфичные для компилятора vsnprintf
(не стандартизованные до C++11), некоторые copy_if<>
(они как-то пропустили это в C++98), собственные охранники мьютексов и не только. При реализации чистого варианта C++11 вы оборачиваете старую (но доверенную) реализацию в какой-то #if __is_extended
(лучше: __is_idosyncratic
или !__is_ANSI_C11
). Новый C++11 идет за #else
. Когда единица перевода, которая по-прежнему компилируется как C++0x или C++98, включает stuff.h, ничего не меняется. Никаких ошибок компиляции, никакого другого поведения во время выполнения. C++11 остается экспериментальным. Код можно безопасно коммитить в основную ветку, коллеги могут изучать его, учиться на нем и применять техники со своими компонентами.
__is_extended
? - person Christian Hackl   schedule 19.07.2015#if __is_extended #error this is portable code #endif
, или, возможно, макросы, такие как#define __is_ANSI_CPP11 (__cplusplus == 201103L && !__is_extended)
. - person Andreas Spindler   schedule 19.07.2015_MSC_EXTENSIONS
будет определено, если вы используете флаг/Ze
. Решение этой проблемы состоит в том, чтобы использовать не/Ze
, а/Za
. Почему вы сначала включили расширения в компиляторе, а затем обработали собственную конфигурацию компилятора как ошибку? - person Christian Hackl   schedule 19.07.2015__is_extended
, является общеупотребительным, но во время разработки он может быть полезен. - person Andreas Spindler   schedule 19.07.2015/Za
и то, что ваш компилятор точно указывает на нестандартные фрагменты кода через полученные сообщения об ошибках, не решить это более элегантно. - person Christian Hackl   schedule 19.07.2015__is_extended
какой-то грязный.#pragma
тоже грязный. Но опять же, что грязного в грязной среде? Я фрилансер уже почти 20 лет. Многие компании не платят деньги за чистый код — им нужна только функциональность. И некоторые люди, которых вы встречаете в проектах, которые делают C++, на самом деле не понимают его. До сих пор нередко просто оборачивать кучу функций C вstruct
и называть это классом. - person Andreas Spindler   schedule 19.07.2015#if __is_extended #error this is portable code #endif
скомпилировать без изменения настроек проекта. Даже если код внутри на самом деле является переносимым. И это не поможет вам обнаружить, просто оберните кучу функций C структурой и назовите ее классом. Итак, какова цель? - person Ben Voigt   schedule 19.07.2015__is_extended
в новом проекте было бы странным, возможно, поэтому в стандарте C++ нет__STDCPLUSPLUS__
. - person Andreas Spindler   schedule 19.07.2015__cplusplus
! - person rubenvb   schedule 03.06.2016