@Mat: Pozowany i zamknięty, ponieważ pytanie było bzdurne i zawierało inne arbitralne bzdury. Opublikowałem to ponownie w przyzwoitej formie. Z przyjemnością zamknę to, jeśli wygląda na to, że oryginał zostanie naprawiony i ożywiony, ale nie wstrzymuję oddechu.
Wyścigi lekkości na orbicie,
1
@Mat: Cóż, najlepszą odpowiedzią nie jest statyczna lista kompilatorów, ale sposób samodzielnego określenia, co jest używane. Więc proszę.
Wyścigi lekkości na orbicie
1
@Als: To będzie wkrótce. Obiecuję. Poza tym c++-faqznacznik nie ma żadnego rzeczywistego warunku wstępnego „ile razy pytano”, które musisz zdać; chodzi bardziej o format i ogólność rzeczy.
Wyścigi lekkości na orbicie
Odpowiedzi:
13
Według mojej wiedzy nie ma ogólnego sposobu, aby to zrobić. Jeśli spojrzysz na nagłówki wieloplatformowych / wielu kompilatorów obsługujących biblioteki, zawsze znajdziesz wiele definicji, które używają konstrukcji specyficznych dla kompilatora do określenia takich rzeczy:
/*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
Prawdopodobnie będziesz musiał sam dokonać takich definicji dla wszystkich kompilatorów, których używasz.
W C ++ 0x makro __cpluspluszostanie ustawione na wartość, która różni się (jest większa) od wartości bieżącej 199711L.
Chociaż nie jest to tak pomocne, jak by się chciało. gcc(najwyraźniej przez prawie 10 lat) miał tę wartość ustawioną na 1, wykluczając jeden główny kompilator, dopóki nie została naprawiona, gdy wyszło gcc 4.7.0 .
Oto standardy C ++ i jakiej wartości powinieneś się spodziewać __cplusplus:
C ++ przed C ++ 98: __cplusplusjest 1.
C ++ 98: __cplusplusjest 199711L.
C ++ 98 + TR1: Czyta się to jako C ++ 98 i nie ma sposobu, aby sprawdzić, czy wiem.
C ++ 11: __cplusplusjest 201103L.
C ++ 14: __cplusplusjest 201402L.
C ++ 17: __cplusplusjest 201703L.
Jeśli kompilator może być starszy gcc, musimy uciec się do hakera specyficznego dla kompilatora (spójrz na makro wersji, porównaj je z tabelą z zaimplementowanymi funkcjami) lub użyj Boost.Config (który zapewnia odpowiednie makra ). Zaletą tego jest to, że możemy faktycznie wybrać określone funkcje nowego standardu i napisać obejście, jeśli brakuje tej funkcji. Jest to często preferowane w stosunku do rozwiązania hurtowego, ponieważ niektóre kompilatory twierdzą, że implementują C ++ 11, ale oferują tylko podzbiór funkcji.
Niestety, dokładniejsze sprawdzanie funkcji (np. Poszczególnych funkcji bibliotecznych, takich jak std::copy_if) może być wykonane tylko w systemie kompilacji Twojej aplikacji (uruchom kod z funkcją, sprawdź, czy skompilował i dało poprawne wyniki - autoconfjest narzędziem z wyboru, jeśli bierzesz ta trasa).
Czy nie wygląda na to, że dostawcy kompilatorów to aktualizują - może czekają, aż w pełni dostosują się do standardu? ( Stackoverflow.com/q/14131454/11698 )
Richard Corden
2
@prnr: To może być prawda, ale to użytkownik, który zadał pytanie, decyduje, którą odpowiedź zaakceptować. W momencie wysłania odpowiedzi, która jest aktualnie oznaczona jako zaakceptowana, była poprawna, więc oryginalny plakat ją zaakceptował. Ten użytkownik może zdecydować o zmianie zaakceptowanej odpowiedzi, ale może nie być już aktywny w serwisie. Zobacz: meta.stackexchange.com/questions/120568/…
Dan Korn
3
vs2017 podaje wartość __cplusplus 199711
Al Mamun
5
@AlMamun Microsoft częściowo naprawiono __cplusplustylko w VS 15.7. Zobacz ich blog zespołu Visual C ++
Ivan_Bereziuk,
1
Link do FAQ jest uszkodzony.
brainplot
38
Proszę uruchomić poniższy kod, aby sprawdzić wersję.
To zabawne, ponieważ w studiach wizualnych wartość __cplusplus to 199711L, a kod, który przesłałeś, zwrócił c ++ 98, jednak użyłem funkcji z c ++ 14, w tym szablonów zmiennych i decltype (auto). Czy jest możliwe, że została zaimplementowana niewłaściwa wersja makra?
@DaanTimmer Jestem zdezorientowany tym artykułem, wydaje się, że zakładam wiedzę o tym, jak używać /Zc:__cplusplusflagi. Nie mogę po prostu std::cout << /Zc:__cplusplus;dlatego, że dwukropki i ukośniki nie mogą być oczywiście częścią nazw zmiennych. Czy jesteś w stanie wyjaśnić, jak to zrobić? Dzięki.
W zależności od tego, co chcesz osiągnąć, Boost.Config może Ci pomóc. Nie zapewnia wykrywania wersji standardowej, ale udostępnia makra, które pozwalają sprawdzić obsługę określonego języka / funkcji kompilatora.
W każdym razie sprawdzanie funkcji jest prawdopodobnie lepszym pomysłem niż sprawdzanie standardowych wersji. Niewiele kompilatorów obsługuje wszystko począwszy od standardu, ale jeśli wszystkie obsługują ograniczoną liczbę potrzebnych funkcji, nie ma znaczenia, czy pozostałe funkcje z danego standardu są zaimplementowane i działają poprawnie.
Rob Kennedy,
4
__cplusplus
W C ++ 0x makro __cplusplus zostanie ustawione na wartość, która różni się od bieżącego 199711L (jest większa niż).
Użyj __cpluspluszgodnie z sugestią. Tylko jedna uwaga dla kompilatora firmy Microsoft, użyj Zc:__cplusplusprzełącznika kompilatora, aby włączyć__cplusplus
To, czy __STDC__jest zdefiniowane i jaka jest jego wartość, są zdefiniowane w implementacji w C ++.
Rob Kennedy,
@Rob: Tak, jest. @Tor: Próbowałem w VC ++ 2005, ale jest napisane, że STDC to niezadeklarowany identyfikator. Jest jednak wymieniony jako jedno z tych wstępnie zdefiniowanych makr. Jednak STDC_VERSION nie istnieje.
jasonline
Informuje o wersji języka programowania C obsługiwanej przez kompilator. Nie mówi nic o obsługiwanej wersji języka C ++.
Dan Molding
0
Zwykle __cplusplusdo wykrywania c ++ 17 należy używać funkcji define, ale domyślnie kompilator firmy Microsoft nie definiuje poprawnie tego makra, patrz https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - potrzebujesz aby zmodyfikować ustawienia projektu, aby uwzględnić /Zc:__cplusplusprzełącznik, lub możesz użyć takiej składni:
c++-faq
znacznik nie ma żadnego rzeczywistego warunku wstępnego „ile razy pytano”, które musisz zdać; chodzi bardziej o format i ogólność rzeczy.Odpowiedzi:
Według mojej wiedzy nie ma ogólnego sposobu, aby to zrobić. Jeśli spojrzysz na nagłówki wieloplatformowych / wielu kompilatorów obsługujących biblioteki, zawsze znajdziesz wiele definicji, które używają konstrukcji specyficznych dla kompilatora do określenia takich rzeczy:
Prawdopodobnie będziesz musiał sam dokonać takich definicji dla wszystkich kompilatorów, których używasz.
źródło
Z FAQ Bjarne Stroustrup C ++ 0x :
Chociaż nie jest to tak pomocne, jak by się chciało.
gcc
(najwyraźniej przez prawie 10 lat) miał tę wartość ustawioną na1
, wykluczając jeden główny kompilator, dopóki nie została naprawiona, gdy wyszło gcc 4.7.0 .Oto standardy C ++ i jakiej wartości powinieneś się spodziewać
__cplusplus
:__cplusplus
jest1
.__cplusplus
jest199711L
.__cplusplus
jest201103L
.__cplusplus
jest201402L
.__cplusplus
jest201703L
.Jeśli kompilator może być starszy
gcc
, musimy uciec się do hakera specyficznego dla kompilatora (spójrz na makro wersji, porównaj je z tabelą z zaimplementowanymi funkcjami) lub użyj Boost.Config (który zapewnia odpowiednie makra ). Zaletą tego jest to, że możemy faktycznie wybrać określone funkcje nowego standardu i napisać obejście, jeśli brakuje tej funkcji. Jest to często preferowane w stosunku do rozwiązania hurtowego, ponieważ niektóre kompilatory twierdzą, że implementują C ++ 11, ale oferują tylko podzbiór funkcji.Wiki Stdcxx zawiera obszerną macierz do obsługi kompilatorów funkcji C ++ 0x (jeśli odważysz się sprawdzić te funkcje samodzielnie).
Niestety, dokładniejsze sprawdzanie funkcji (np. Poszczególnych funkcji bibliotecznych, takich jak
std::copy_if
) może być wykonane tylko w systemie kompilacji Twojej aplikacji (uruchom kod z funkcją, sprawdź, czy skompilował i dało poprawne wyniki -autoconf
jest narzędziem z wyboru, jeśli bierzesz ta trasa).źródło
__cplusplus
tylko w VS 15.7. Zobacz ich blog zespołu Visual C ++Proszę uruchomić poniższy kod, aby sprawdzić wersję.
źródło
/Zc:__cplusplus
)/Zc:__cplusplus
flagi. Nie mogę po prostustd::cout << /Zc:__cplusplus;
dlatego, że dwukropki i ukośniki nie mogą być oczywiście częścią nazw zmiennych. Czy jesteś w stanie wyjaśnić, jak to zrobić? Dzięki.W zależności od tego, co chcesz osiągnąć, Boost.Config może Ci pomóc. Nie zapewnia wykrywania wersji standardowej, ale udostępnia makra, które pozwalają sprawdzić obsługę określonego języka / funkcji kompilatora.
źródło
C ++ 0x FAQ autorstwa BS
źródło
Użyj
__cplusplus
zgodnie z sugestią. Tylko jedna uwaga dla kompilatora firmy Microsoft, użyjZc:__cplusplus
przełącznika kompilatora, aby włączyć__cplusplus
Źródło https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
źródło
Po szybkim wygooglowaniu :
__STDC__
i__STDC_VERSION__
zobacz tutajźródło
__STDC__
jest zdefiniowane i jaka jest jego wartość, są zdefiniowane w implementacji w C ++.Zwykle
__cplusplus
do wykrywania c ++ 17 należy używać funkcji define, ale domyślnie kompilator firmy Microsoft nie definiuje poprawnie tego makra, patrz https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - potrzebujesz aby zmodyfikować ustawienia projektu, aby uwzględnić/Zc:__cplusplus
przełącznik, lub możesz użyć takiej składni:źródło