Як визначити версію стандарту C ++, що використовується компілятором?


114

Як визначити, яку версію стандарту C ++ реалізує ваш компілятор? Наскільки я знаю, нижче знаходяться стандарти, які я знав:

  • C ++ 03
  • C ++ 98

3
Ви позначили цей c ++ , але два з трьох перелічених вами стандартів не є стандартами C ++. Якими мовами ви цікавитесь?
Роб Кеннеді

1
І це питання було задано всього пару хвилин тому. ( stackoverflow.com/questions/7132440/… )
Мат

1
@Mat: Поставлено і закрито, тому що питання було сміттям і в ньому були якісь інші довільні нісенітниці. Я переопублікував це у гідній формі. Я був би радий закрити цю, якщо схоже, що оригінал буде виправлений і відновлений, але я не затримую дихання.
Гонки легкості на орбіті

1
@Mat: Ну найкраща відповідь - це не статичний перелік компіляторів, а засіб визначення для себе того, що використовується. Так що ви йдете.
Гонки легкості по орбіті

1
@Als: Скоро буде. Я обіцяю. Крім того, c++-faqтег не має жодної фактичної попередньої необхідної необхідної кількості запитів, яку потрібно пройти; мова йде більше про формат і загальність речі.
Гонки легкості по орбіті

Відповіді:


13

Наскільки мені відомо, загального способу це зробити не існує. Якщо ви подивитеся на заголовки крос-платформних / декількох компіляторів, що підтримують бібліотеки, ви завжди знайдете безліч визначень, які використовують конкретні компіляторні конструкції для визначення таких речей:

/*Define Microsoft Visual C++ .NET (32-bit) compiler */
#if (defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER >= 1300)
     ...
#endif

/*Define Borland 5.0 C++ (16-bit) compiler */
#if defined(__BORLANDC__) && !defined(__WIN32__)
     ...
#endif

Вам, мабуть, доведеться робити таке визначення для всіх компіляторів, якими ви користуєтеся.


1
Хоча це не моя очікувана відповідь, але я думаю, просто немає універсального способу її пошуку.
jasonline

246

Від Bjarne Stroustrup C ++ 0x FAQ :

__cplusplus

У C ++ 0x макросу __cplusplusбуде встановлено значення, яке відрізняється від (більше, ніж) поточного 199711L.

Хоча це не так корисно, як хотілося б. gcc(мабуть, протягом майже 10 років) було встановлено це значення 1, виключаючи одного основного компілятора, поки воно не було встановлено, коли вийшов gcc 4.7.0 .

Це стандарти C ++, і яке значення ви повинні мати на очікування у __cplusplus:

  • C ++ pre-C ++ 98: __cplusplusє 1.
  • C ++ 98: __cplusplusє 199711L.
  • C ++ 98 + TR1: Це означає, що C ++ 98, і немає можливості перевірити, що я знаю.
  • C ++ 11: __cplusplusє 201103L.
  • C ++ 14: __cplusplusє 201402L.
  • C ++ 17: __cplusplusє 201703L.

Якщо компілятор може бути старшим gcc, нам потрібно вдатися до конкретного хакерського компілятора (подивіться на макрос версії, порівняйте його з таблицею з реалізованими функціями) або скористайтеся Boost.Config (який надає відповідні макроси ). Перевагою цього є те, що ми фактично можемо вибрати конкретні особливості нового стандарту та написати вирішення, якщо функція відсутня. Це часто надається перевагу над оптовим рішенням, оскільки деякі компілятори вимагають впровадити C ++ 11, але пропонують лише підмножину функцій.

У Stdcxx Wiki розміщена вичерпна матриця для підтримки компілятора функцій C ++ 0x (якщо ви зважилися перевірити їх на себе).

На жаль, більш точну перевірку функцій (наприклад, окремих функцій бібліотеки на зразок std::copy_if) можна здійснити лише в системі збирання вашої програми (запустіть код за допомогою функції, перевірте, чи вона зібрала та дали правильні результати - autoconfце інструмент вибору, якщо брати цей маршрут).


Не схоже, що постачальники компіляторів це оновлюють - можливо, вони чекають, поки вони повністю відповідають стандарту? ( Stackoverflow.com/q/14131454/11698 )
Річард Корден

2
@prnr: Це може бути правдою, але вирішити, яку відповідь прийняти, залежить від користувача, який задав питання. На той момент, коли була розміщена відповідь, яка на даний момент позначена як прийнята, вона була правильною, тому оригінальний плакат прийняв її. Цей користувач може вирішити змінити прийняту відповідь, але він може більше не бути активним на сайті. Дивіться: meta.stackexchange.com/questions/120568/…
Dan Korn

3
vs2017 дає значення __cplusplus 199711
Аль Мамун

5
@AlMamun Microsoft частково зафіксована __cplusplusлише у VS 15.7. Дивіться їхній блог Visual C ++ Team
Ivan_Bereziuk

1
Посилання на поширені запитання порушено.
brainplot

38

Будь ласка, запустіть наступний код, щоб перевірити версію.

#include<iostream>

int main() {
    if (__cplusplus == 201703L) std::cout << "C++17\n";
    else if (__cplusplus == 201402L) std::cout << "C++14\n";
    else if (__cplusplus == 201103L) std::cout << "C++11\n";
    else if (__cplusplus == 199711L) std::cout << "C++98\n";
    else std::cout << "pre-standard C++\n";
}

8
Це смішно, тому що у візуальних студіях значення __cplusplus становить 199711L, а код, який ви опублікували, повернув c ++ 98, однак, я використовував функції c ++ 14, включаючи змінні шаблони та decltype (auto). Чи можлива неправильна версія макросу?
Колін Хікс

2
Дивіться: devblogs.microsoft.com/cppblog/… (TLDR: вказати прапор /Zc:__cplusplus)
Даан Тіммер

@DaanTimmer Мене бентежить ця стаття, здається, вона припускає знання, як використовувати /Zc:__cplusplusпрапор. Я не можу просто std::cout << /Zc:__cplusplus;тому, що колонки і косої риси не можуть бути частиною імен змінних. Чи можете ви пояснити, як це зробити? Дякую.
A__


7

Залежно від того, що ви хочете досягти, Boost.Config може допомогти вам. Він не забезпечує виявлення стандартної версії, але надає макроси, за допомогою яких можна перевірити підтримку певної мови / функції компілятора.


3
Перевірка можливостей - це, мабуть, краща ідея, ніж перевірка стандартних версій. Мало хто з компіляторів підтримує все від стандарту, але якщо всі вони підтримують обмежену кількість потрібних вам функцій, то насправді не має значення, чи решта функцій із заданого стандарту реалізовані та працюють правильно.
Роб Кеннеді



0

Після швидкого гугл :

__STDC__і __STDC_VERSION__, дивіться тут


Чи __STDC__визначено, і яке його значення, визначено реалізацією в C ++.
Роб Кеннеді

@Rob: Так, так і є. @Tor: Я спробував у VC ++ 2005, але він говорить, що STDC є незадекларованим ідентифікатором. Він входить як один із тих заздалегідь визначених макросів. Однак STDC_VERSION не існує.
Jasonline

Це говорить вам про версію мови програмування на C, що підтримується компілятором. Це нічого не говорить про підтримувану версію мови C ++.
Дан Ліплення

0

Як правило , ви повинні використовувати __cplusplusвизначаєте для виявлення 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.