Какова ценность __cplusplus для С++ 17?
Мы пытаемся проверить код под С++ 17 и его изменить на std::uncaught_exception
. Я не могу заставить GCC предоставить значение __cplusplus
:
$ /opt/local/bin/g++ -std=c++17 -dM -E - </dev/null | grep __cplusplus
cc1: warning: command line option '-std=c++1z' is valid for C++/ObjC++ but not for C
$
и
$ /opt/local/bin/g++ --version
g++-mp-6 (MacPorts gcc6 6.1.0_0) 6.1.0
Copyright (C) 2016 Free Software Foundation, Inc.
Каково значение __cplusplus
при использовании С++ 17?
Ответы
Ответ 1
Каково значение __cplusplus
при использовании С++ 17?
В соответствии с проектом стандарта N4594 §16.8/p1 Предопределенные имена макросов [cpp.predefined] (Emphasis Mine):
При этом будут определены следующие имена макросов: __cplusplus
Имя __cplusplus
определяется значением 201402L при компиляции единицы перевода С++. 156
156). Предполагается, что будущие версии этого стандарта будут замените значение этого макроса на большее значение. Несогласованный компиляторы должны использовать значение не более пяти десятичных цифр.
Однако такое же значение назначается для стандарта С++ 14. По-видимому, кажется, что стандартного значения __cplusplus
еще не установлено для стандарта С++ 17.
В версиях GCC 6.1 и 7.0 значение изменяется на 201500
Live Demo
В версии Clang 3.8 и 3.9 значение не изменяется 201406.
Следовательно, вам придется немного подождать, пока выйдет стандартное значение.
--- Обновить ---
В соответствии со стандартом С++ §19.8/p1 Предопределенные имена макросов [cpp.predefined] (Emphasis Mine):
1 Следующие имена макросов должны быть определены реализация:
__cplusplus
Целый литерал 201703L.
Таким образом, значение __cplusplus
при использовании С++ 17 должно быть 201703L.
Ответ 2
Я бы попробовал
#if __cplusplus > 201402L
// C__17 code here
...
#endif
Другими словами, тестирование более чем на С++ 14 должно работать, поскольку компиляторы добавляют дополнительные функции.
Как упоминалось выше, gcc использует 201500L. Похоже, что clang использует 201406L (через четыре месяца после С++ 14).
Использование вышеперечисленного должно быть кросс-платформенным и работать, даже когда С++ 17 выйдет с реальным значением для __cplusplus. Для получения дополнительной информации об эволюционных функциях попробуйте макросы тестирования функций.
Ответ 3
Я понимаю, что вы задавали этот вопрос, ссылаясь на компилятор Gnu C++, который вы используете, но вы, возможно, захотите узнать, что происходит с компилятором Visual C++, и, строго говоря, ваш вопрос не задавался о конкретном компиляторе.
В настоящее время, на дату этой публикации, компилятор V C++ 2017 устанавливает __cplusplus
на 199711L
, а не то, что вы могли бы ожидать, если вы установите компилятор на использование C++ 17.
Чтобы он правильно отображал отчет, вы также должны установить /Zc:__cplusplus
.
(источник: https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017)
А почему? Ну... по их словам:
Мы попытались обновить макрос по умолчанию и обнаружили, что код не компилируется правильно, когда мы меняем значение __cplusplus.
(источник: https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/)
Ответ 4
Я действительно не знаю, почему __cplusplus
не отображается как обычный макрос, но я предполагаю, что вы не можете переопределить его. Вот как я определяю его значение.
#include <iostream>
int main( int argc, char** argv )
{
std::cout << __cplusplus << std::endl;
return 0;
}
Затем компиляция показывает значение.
$ g++-6 test.cpp && ./a.out
201402
$ g++-6 -std=c++17 test.cpp && ./a.out
201500
Я бы проверил, не является ли это >= 201500
, а не проверяет любое конкретное значение.
Ответ 5
Обычно вы должны использовать __cplusplus
define для обнаружения c ++ 17, но по умолчанию компилятор Microsoft не определяет этот макрос должным образом, см. https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - вам нужно либо изменить настройки проекта, чтобы включить переключатель /Zc:__cplusplus
, либо вы можете использовать такой синтаксис:
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
//C++17 specific stuff here
#endif