Derleyici tarafından kullanılan C ++ standardının sürümü nasıl belirlenir?


116

Derleyiciniz tarafından C ++ standardının hangi sürümünün uygulandığını nasıl belirlersiniz? Bildiğim kadarıyla, bildiğim standartlar aşağıdadır:

  • C ++ 03
  • C ++ 98

3
Bu c ++ 'ı etiketlediniz , ancak listelediğiniz üç standarttan ikisi C ++ standartları değil. Hangi dil (ler) le ilgileniyorsunuz?
Rob Kennedy

1
Ve soru birkaç dakika önce soruldu. ( stackoverflow.com/questions/7132440/… )
Mat

1
@Mat: Soru saçma olduğu ve üzerinde başka keyfi saçmalıklar olduğu için poz verdi ve kapatıldı. İyi bir biçimde yeniden gönderdim. Orijinali düzeltilip yeniden canlandırılacak gibi görünüyorsa bunu kapatmaktan mutluluk duyarım ama nefesimi tutmuyorum.
Orbit'te Hafiflik Yarışları

1
@Mat: En iyi cevap statik bir derleyiciler listesi değil, neyin kullanıldığını kendiniz belirlemenin bir yoludur . Al işte ozaman, buyur.
Orbit'te Hafiflik Yarışları

1
@Als: Yakında olacak. Söz veriyorum. Ayrıca, c++-faqetiketinde geçmeniz gereken "kaç kez sorulduğu" için gerçek bir ön koşul yoktur; daha çok şeyin biçimi ve genelliği ile ilgilidir.
Orbit'te Hafiflik Yarışları

Yanıtlar:


13

Bildiğim kadarıyla bunu yapmanın genel bir yolu yok. Çapraz platform / çoklu derleyicinin kitaplıkları destekleyen başlıklarına bakarsanız, her zaman bu tür şeyleri belirlemek için derleyiciye özel yapılar kullanan birçok tanım bulacaksınız :

/*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

Muhtemelen kullandığınız tüm derleyiciler için bu tür tanımları kendiniz yapmanız gerekecektir.


1
Beklediğim yanıt bu değil ama sanırım bunu bulmanın evrensel bir yolu yok.
jasonline

248

Bjarne Stroustrup C ++ 0x SSS'den :

__cplusplus

C ++ 0x'de makro __cplusplus, mevcut değerden farklı (daha büyük) bir değere ayarlanacaktır 199711L.

Bu, birinin istediği kadar yararlı olmasa da. gcc(görünüşe göre yaklaşık 10 yıldır) bu değer 1, gcc 4.7.0 çıktığında düzeltilene kadar büyük bir derleyiciyi dışarıda bırakarak olarak ayarlanmıştı .

Bunlar C ++ standartlarıdır ve aşağıdakilerden hangi değeri beklemeniz gerekir __cplusplus:

  • C ++ C ++ 98 öncesi: __cplusplusis 1.
  • C ++ 98: __cplusplusolur 199711L.
  • C ++ 98 + TR1: Bu, C ++ 98 olarak okuyor ve bildiğimi kontrol etmenin bir yolu yok.
  • C ++ 11: __cplusplusolur 201103L.
  • C ++ 14: __cplusplusolur 201402L.
  • C ++ 17: __cplusplusolur 201703L.

Derleyici daha eski olabilirse gcc, derleyiciye özgü bilgisayar korsanlığına başvurmalıyız (bir sürüm makrosuna bakmalı, onu uygulanan özelliklere sahip bir tabloyla karşılaştırmalıyız) veya Boost.Config ( ilgili makroları sağlayan ) kullanmalıyız. Bunun avantajı, yeni standardın belirli özelliklerini gerçekten seçebilmemiz ve özellik eksikse bir geçici çözüm yazabilmemizdir. Bu genellikle bir toptan çözüme göre tercih edilir, çünkü bazı derleyiciler C ++ 11'i uyguladığını iddia eder, ancak özelliklerin yalnızca bir alt kümesini sunar.

Stdcxx Wiki , C ++ 0x özelliklerinin derleyici desteği için kapsamlı bir matris barındırır (özellikleri kendiniz kontrol etmeye cesaret ederseniz).

Ne yazık ki, özelliklerin daha hassas bir şekilde kontrol edilmesi (örneğin, bireysel kütüphane işlevleri gibi std::copy_if) yalnızca uygulamanızın derleme sisteminde yapılabilir (özellik ile kod çalıştırın, derlenip derlenmediğini ve doğru sonuçlar üretip üretmediğini kontrol edin - alıyorsanız autoconftercih edilen araçtır. bu rota).


Derleyici satıcıları bunu güncellemiyor gibi görünmüyor - belki de standarda tam olarak uyana kadar bekliyorlar? ( Stackoverflow.com/q/14131454/11698 )
Richard Corden

2
@prnr: Bu doğru olabilir, ancak hangi cevabın kabul edileceğine soruyu soran kullanıcıya bağlıdır. Şu anda kabul edildi olarak işaretlenen yanıtın gönderildiği sırada, yanıt doğruydu, bu nedenle orijinal gönderen bunu kabul etti. Bu kullanıcı, kabul edilen cevabı değiştirmeye karar verebilir, ancak artık sitede aktif olmayabilir. Bakınız: meta.stackexchange.com/questions/120568/…
Dan Korn

3
vs2017 __cplusplus'ın değerini verir 199711
Al Mamun

5
@AlMamun Microsoft, __cplusplusyalnızca VS 15.7'de kısmen düzeltildi . Onların Bkz Visual C ++ Takım Blog
Ivan_Bereziuk

1
SSS bağlantısı kesildi.
brainplot

39

Lütfen sürümü kontrol etmek için aşağıdaki kodu çalıştırın.

#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
Komik, çünkü görsel stüdyolarda __cplusplus değeri 199711L ve gönderdiğiniz kod c ++ 98 döndürdü, ancak değişken şablonlar ve decltype (otomatik) dahil olmak üzere c ++ 14'ün özelliklerini kullandım. Makronun yanlış versiyonu uygulanmış olabilir mi?
Colin Hicks

2
Bakınız: devblogs.microsoft.com/cppblog/… (TLDR: bayrağı belirtin /Zc:__cplusplus)
Daan Timmer

@DaanTimmer Bu yazı beni şaşırttı, /Zc:__cplusplusbayrağın nasıl kullanılacağına dair bilgim var gibi görünüyor . Basitçe yapamam std::cout << /Zc:__cplusplus;çünkü iki nokta üst üste ve eğik çizgiler elbette değişken adların parçası olamaz. Bunun nasıl yapılacağını açıklayabilir misin? Teşekkürler.
A__


7

Neyi başarmak istediğinize bağlı olarak, Boost.Config size yardımcı olabilir. Standart sürümün algılanmasını sağlamaz, ancak belirli dil / derleyici özelliklerinin desteğini kontrol etmenizi sağlayan makrolar sağlar.


3
Özellikleri kontrol etmek muhtemelen standart sürümleri kontrol etmekten daha iyi bir fikirdir. Çok az derleyici , bir standarttan her şeyi destekler , ancak hepsi ihtiyacınız olan sınırlı sayıda özelliği destekliyorsa, belirli bir standarttaki diğer özelliklerin uygulanıp uygulanmadığı ve doğru çalışıp çalışmadığı gerçekten önemli değildir.
Rob Kennedy



0

Hızlı bir google'dan sonra :

__STDC__ve buraya__STDC_VERSION__ bakın


İster __STDC__tanımlanmış ve bunun değerinin ne, ++ uygulama tanımlı C içindedir edilir.
Rob Kennedy

@Rob: Evet, öyle. @Tor: VC ++ 2005'te denedim ama STDC'nin bildirilmemiş bir tanımlayıcı olduğunu söylüyor . Yine de bu önceden tanımlanmış makrolardan biri olarak listelenmiştir. Ancak, STDC_VERSION mevcut değil.
jasonline

Bu size derleyici tarafından desteklenen C programlama dilinin sürümünü söyler. Desteklenen C ++ dilinin sürümü hakkında size hiçbir şey söylemez.
Dan Molding

0

Normalde __cplusplusc ++ 17'yi algılamak için tanımlamayı kullanmanız gerekir , ancak varsayılan olarak microsoft derleyicisi bu makroyu doğru şekilde tanımlamaz, bkz. Https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - ihtiyacınız var proje ayarlarını /Zc:__cplusplusanahtar içerecek şekilde değiştirmek için veya aşağıdaki gibi sözdizimini kullanabilirsiniz:

#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
     //C++17 specific stuff here
#endif
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.