컴파일러에서 사용하는 C ++ 표준의 버전을 확인하는 방법은 무엇입니까?


114

컴파일러에서 구현 한 C ++ 표준의 버전을 어떻게 결정합니까? 내가 아는 한 다음은 내가 알고있는 표준입니다.

  • C ++ 03
  • C ++ 98

3
C ++에 태그를 지정 했지만 나열된 세 가지 표준 중 두 가지는 C ++ 표준이 아닙니다. 어떤 언어에 관심이 있습니까?
Rob Kennedy

1
그리고 몇 분 전에 질문을 받았습니다. ( stackoverflow.com/questions/7132440/… )
Mat

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

247

Bjarne Stroustrup C ++ 0x FAQ에서 :

__cplusplus

C ++ 0x에서 매크로 __cplusplus는 현재와 다른 (보다 큰) 값으로 설정됩니다 199711L.

이것이 원하는만큼 도움이되지는 않지만. gcc(분명히 거의 10 년 동안)이 값을로 설정하여 gcc 4.7.0이 나왔을 때 수정 될 때1 까지 하나의 주요 컴파일러를 배제 했습니다 .

다음은 C ++ 표준이며 다음에서 기대할 수있는 가치입니다 __cplusplus.

  • C ++에서 98-C를 사전 ++ __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 )
리처드 Corden

2
@prnr : 사실 일 수 있지만 어떤 답변을 수락할지 결정하는 것은 질문을 한 사용자에게 달려 있습니다. 현재 수락 된 것으로 표시된 답변이 게시되었을 당시에는 정확했기 때문에 원본 포스터가 수락했습니다. 해당 사용자는 수락 된 답변을 변경하기로 결정할 수 있지만 사이트에서 더 이상 활성 상태가 아닐 수 있습니다. 참조 : meta.stackexchange.com/questions/120568/…
Dan Korn

3
vs2017는 __cplusplus의 가치 199,711 제공
알 Mamun

5
@AlMamun Microsoft __cplusplus는 VS 15.7에서만 부분적으로 수정 되었습니다. 그들의 참조 비주얼 C ++ 팀 블로그
Ivan_Bereziuk

1
FAQ 링크가 깨졌습니다.
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을 반환했기 때문에 재미 있지만, 변수 템플릿과 decltype (auto)를 포함하여 C ++ 14의 기능을 사용했습니다. 매크로의 잘못된 버전이 구현되었을 수 있습니까?
Colin Hicks

2
참조 : devblogs.microsoft.com/cppblog/… (TLDR : 플래그 지정 /Zc:__cplusplus)
Daan Timmer

@DaanTimmer 나는 그 기사로 인해 혼란스럽고 /Zc:__cplusplus깃발 을 사용하는 방법에 대한 지식을 가정하는 것 같습니다 . std::cout << /Zc:__cplusplus;물론 콜론과 슬래시가 변수 이름의 일부가 될 수 없기 때문에 그럴 수 없습니다 . 이 작업을 수행하는 방법을 설명 할 수 있습니까? 감사.
A__


7

달성하려는 목표에 따라 Boost.Config 가 도움이 될 수 있습니다. 표준 버전 감지 기능은 제공하지 않지만 특정 언어 / 컴파일러 기능 지원 여부를 확인할 수있는 매크로를 제공합니다.


3
어쨌든 기능을 확인하는 것이 표준 버전을 확인하는 것보다 더 나은 생각 일 것입니다. 표준의 모든 기능 을 지원 하는 컴파일러는 거의 없지만 모두 필요한 기능을 제한적으로 지원한다면 주어진 표준의 나머지 기능이 제대로 구현되고 작동하는지 여부는 중요하지 않습니다.
Rob Kennedy



0

빠른 Google 후 :

__STDC____STDC_VERSION__, 여기를 참조 하십시오.


__STDC__정의 여부 와 그 값은 C ++에서 구현 정의됩니다.
Rob Kennedy

@Rob : 네, 그렇습니다. @Tor : VC ++ 2005에서 시도했지만 STDC 가 선언되지 않은 식별자 라고 말합니다 . 그러나 사전 정의 된 매크로 중 하나로 나열됩니다. 그러나 STDC_VERSION 은 존재하지 않습니다.
jasonline 2010

이것은 컴파일러가 지원하는 C 프로그래밍 언어의 버전을 알려줍니다. 지원되는 C ++ 언어 버전에 대한 정보가 없습니다.
Dan Molding

0

일반적으로 사용한다 __cplusplusC ++ (17)를 감지하는 정의하지만 기본적으로 마이크로 소프트 컴파일러가 제대로 그 매크로를 정의하지 않습니다를 참조 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.