¿Cómo determinar la versión del estándar C ++ utilizada por el compilador?


114

¿Cómo se determina qué versión del estándar C ++ implementa su compilador? Hasta donde yo sé, a continuación están los estándares que he conocido:

  • C ++ 03
  • C ++ 98

3
Etiquetó este c ++ , pero dos de los tres estándares que enumeró no son estándares de C ++. ¿En qué idioma (s) estás interesado?
Rob Kennedy

1
Y la pregunta se hizo hace apenas un par de minutos. ( Stackoverflow.com/questions/7132440/... )
Mat

1
@Mat: planteado y cerrado porque la pregunta era una tontería y tenía otras tonterías arbitrarias a cuestas. Lo he vuelto a publicar en una forma decente. Estaría feliz de cerrar este si parece que el original se arreglará y revivirá, pero no estoy conteniendo la respiración.
Lightness Races in Orbit

1
@Mat: Bueno, la mejor respuesta no es una lista estática de compiladores, sino un medio para determinar por sí mismo lo que está en uso. Ahí vas.
Lightness Races in Orbit

1
@Als: Será pronto. Lo prometo. Además, la c++-faqetiqueta no tiene ningún prerrequisito real "número de veces solicitado" que deba pasar; se trata más del formato y la generalidad de la cosa.
Lightness Races in Orbit

Respuestas:


13

Según mi conocimiento, no existe una forma general de hacer esto. Si observa los encabezados de las bibliotecas de soporte de compiladores múltiples / multiplataforma, siempre encontrará muchas definiciones que usan construcciones específicas del compilador para determinar tales cosas:

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

Probablemente tendrá que hacer esas definiciones usted mismo para todos los compiladores que utilice.


1
Sin embargo, no es mi respuesta esperada, pero supongo que no hay una forma universal de averiguarlo.
Jasonline

246

De las preguntas frecuentes de Bjarne Stroustrup C ++ 0x :

__cplusplus

En C ++ 0x, la macro __cplusplusse establecerá en un valor que difiera de (sea mayor que) el actual 199711L.

Aunque esto no es tan útil como a uno le gustaría. gcc(aparentemente durante casi 10 años) tenía este valor establecido en 1, descartando un compilador principal, hasta que se corrigió cuando salió gcc 4.7.0 .

Estos son los estándares de C ++ y el valor que debería poder esperar en __cplusplus:

  • C ++ anterior a C ++ 98: __cpluspluses 1.
  • C ++ 98: __cpluspluses 199711L.
  • C ++ 98 + TR1: Esto se lee como C ++ 98 y no hay forma de verificar que yo sepa.
  • C ++ 11: __cpluspluses 201103L.
  • C ++ 14: __cpluspluses 201402L.
  • C ++ 17: __cpluspluses 201703L.

Si el compilador puede ser más antiguo gcc, debemos recurrir a la piratería informática específica del compilador (mire una macro de versión, compárela con una tabla con características implementadas) o use Boost.Config (que proporciona macros relevantes ). La ventaja de esto es que realmente podemos elegir características específicas del nuevo estándar y escribir una solución si falta la característica. Esto a menudo se prefiere a una solución mayorista, ya que algunos compiladores afirmarán que implementan C ++ 11, pero solo ofrecen un subconjunto de las características.

El Stdcxx Wiki alberga una matriz completa para el soporte del compilador de las características de C ++ 0x (si se atreve a verificar las características usted mismo).

Desafortunadamente, una verificación más detallada de características (por ejemplo, funciones de biblioteca individuales como std::copy_if) solo se puede realizar en el sistema de compilación de su aplicación (ejecute el código con la característica, verifique si se compiló y produjo resultados correctos: autoconfes la herramienta de elección si toma esta ruta).


No parece que los proveedores de compiladores estén actualizando esto, ¿tal vez estén esperando hasta que cumplan completamente con el estándar? ( Stackoverflow.com/q/14131454/11698 )
Richard Corden

2
@prnr: Eso puede ser cierto, pero depende del usuario que hizo la pregunta decidir qué respuesta aceptar. En el momento en que se publicó la respuesta que actualmente está marcada como aceptada, era correcta, por lo que el cartel original la aceptó. Ese usuario podría decidir cambiar la respuesta aceptada, pero es posible que ya no esté activo en el sitio. Ver: meta.stackexchange.com/questions/120568/…
Dan Korn

3
vs2017 da el valor de __cplusplus 199711
Al Mamun

5
@AlMamun Microsoft se corrigió parcialmente __cplusplussolo en VS 15.7. Vea su Blog del equipo de Visual C ++
Ivan_Bereziuk

1
El enlace a las preguntas frecuentes está roto.
brainplot

38

Por favor, ejecute el siguiente código para verificar la versió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
Es gracioso, porque en los estudios visuales el valor de __cplusplus es 199711L y el código que publicaste devolvió c ++ 98, sin embargo, he usado características de c ++ 14, incluidas plantillas variables y decltype (auto). ¿Es posible que se haya implementado la versión incorrecta de la macro?
Colin Hicks

2
Ver: devblogs.microsoft.com/cppblog/… (TLDR: especificar la bandera /Zc:__cplusplus)
Daan Timmer

@DaanTimmer Estoy confundido por ese artículo, parece asumir el conocimiento de cómo usar la /Zc:__cplusplusbandera. No puedo simplemente std::cout << /Zc:__cplusplus;porque los dos puntos y las barras inclinadas no pueden ser parte de los nombres de las variables, por supuesto. ¿Puede explicar cómo hacer esto? Gracias.
A__


7

Dependiendo de lo que desee lograr, Boost.Config podría ayudarlo. No proporciona detección de la versión estándar, pero proporciona macros que le permiten comprobar el soporte de características específicas de lenguaje / compilador.


3
De todos modos, verificar las características es probablemente una mejor idea que verificar las versiones estándar. Pocos compiladores admiten todo, desde un estándar, pero si todos admiten el número limitado de características que necesita, entonces realmente no importa si el resto de las características de un estándar dado están implementadas y funcionan correctamente.
Rob Kennedy



0

Después de un google rápido :

__STDC__y __STDC_VERSION__mira aquí


Si __STDC__está definido y cuál es su valor, está definido por implementación en C ++.
Rob Kennedy

@Rob: Sí, lo es. @Tor: Lo intenté en VC ++ 2005 pero dice que STDC es un identificador no declarado. Sin embargo, aparece como una de esas macros predefinidas. Sin embargo, STDC_VERSION no existe.
Jasonline

Esto le indica la versión del lenguaje de programación C compatible con el compilador. No le dice nada sobre la versión del lenguaje C ++ que se admite.
Dan Moulding

0

Normalmente, debe usar __cplusplusdefine para detectar c ++ 17, pero de forma predeterminada, el compilador de microsoft no define esa macro correctamente, consulte https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - necesita para modificar la configuración del proyecto para incluir el /Zc:__cpluspluscambio, o puede usar una sintaxis como esta:

#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
     //C++17 specific stuff here
#endif
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.