compilador - ¿Qué estándar de C++ es el predeterminado al compilar con g++?
gcc linux (7)
Tengo una pieza de código que se parece a la siguiente. Digamos que está en un archivo llamado example.cpp
#include <fstream>
#include <string> // line added after edit for clarity
int main() {
std::string filename = "input.txt";
std::ifstream in(filename);
return 0;
}
En una ventana, si escribo en el cmd
el comando g++ example.cpp
, fallará. Creo que es una larga lista de errores, principalmente debido a que el vinculador se quejó de no poder convertir de string
a const char*
.
Pero si ejecuto el compilador utilizando un argumento adicional como el siguiente: g++ -std=c++17 example.cpp
, se compilará y funcionará bien sin problemas.
¿Qué pasa cuando ejecuto el comando anterior? Supongo que se llama a una versión predeterminada del compilador de C ++, pero no sé cuál. Y como programador / desarrollador, ¿debería usar siempre el último comando con el argumento adicional?
Supongo que se llama a una versión predeterminada del compilador de C ++, pero no sé cuál?
Esto solo se puede adivinar leyendo la documentación de su versión particular del compilador.
Si utiliza un GCC reciente , le recomiendo que primero comprenda qué versión está usando ejecutando
g++ -v
o
g++ --version
y luego referirse a la versión de la versión particular de GCC. Por ejemplo, para GCC 7, lea los cambios de GCC 7, etc.
Alternativamente, ejecute
g++ -dumpspecs
y descifra el archivo por defecto llamado spec .
Por cierto, puede asegurarse (por ejemplo, en algunos de sus archivos de encabezado comunes) que C ++ es al menos C ++ 17 mediante la codificación
#if __cplusplus < 201412L
#error expecting C++17 standard
#endif
Y realmente recomiendo hacerlo de esa manera.
PD. En realidad, piense que C ++ 98 y C ++ 17 son dos idiomas diferentes (p. Ej., Como Ocaml4 y C ++ 11). Exija a su usuario que tenga un compilador que admita algún estándar de lenguaje definido (por ejemplo, C ++ 11), no una versión particular de GCC . Lea también sobre los administradores de paquetes .
Al escribir g++ --version
en el comando shell, se revelará la versión del compilador, y de ahí puede inferir el estándar predeterminado. Así que no puedes decirlo directamente, pero puedes inferirlo , con un poco de esfuerzo.
Se supone que los compiladores #define
__cplusplus
que se pueden usar para extraer el estándar que pretenden implementar en tiempo de compilación; pero muchos no lo hacen todavía.
(Y no olvide incluir todos los encabezados de la biblioteca estándar de C ++ que necesita: ¿dónde está el de std::string
por ejemplo? No confíe en la implementación de la biblioteca estándar de C ++, incluidos otros encabezados de forma automática; escritura portable C ++.)
Creo que es posible decirlo mirando la página del manual (al menos para g ++):
Bajo la descripción de -std
, la página del manual enumera todos los estándares de C ++, incluidos los dialectos de GNU. Según una norma específica, se establece de manera bastante discreta, This is the default for C++ code.
(hay una declaración análoga para los estándares C: This is the default for C code.
).
Por ejemplo, para g++/gcc version 5.4.0
, esto se encuentra listado en gnu++98/gnu++03
, mientras que para g++/gcc version 6.4.0
, esto se encuentra listado en gnu++14
.
La página del manual de g ++ en realidad dice cuál es el estándar predeterminado para el código C ++.
Utilice el siguiente script para mostrar la parte relevante:
man g++ | col -b | grep -B 1 -e ''-std.* default''
Por ejemplo, en RHEL 6 g ++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23), la salida:
gnu++98
GNU dialect of -std=c++98. This is the default for C++ code.
Y en Fedora 28 g ++ (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1), la salida:
gnu++1y
GNU dialect of -std=c++14. This is the default for C++ code. The name gnu++1y is deprecated.
Si su versión de g++
es posterior a la 4.7, creo que puede encontrar la versión predeterminada del estándar de C ++ admitida así:
g++ -dM -E -x c++ /dev/null | grep -F __cplusplus
Un ejemplo de mi máquina:
mburr@mint17 ~ $ g++ --version | head -1
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
mburr@mint17 ~ $ g++ -dM -E -x c++ /dev/null | grep -F __cplusplus
#define __cplusplus 199711L
Algunas referencias:
- Detalles sobre las opciones de
g++
utilizadas. - Por qué esto solo funciona para
g++
4.7 o posterior
Su pregunta es específica de los compiladores GNU, por lo que probablemente sea mejor etiquetarla adecuadamente, en lugar de solo C ++ y C ++ 11.
Su código se compilará con los compiladores (y las bibliotecas asociadas) compatibles con C ++ 11 y posteriores.
La razón es que C ++ 11 introdujo un constructor std::ifstream
que acepta un const std::string &
. Antes de C ++ 11, no se podía pasar una std::string
, y sería necesario en su código pasar el filename.c_str()
lugar del filename
de filename
.
Según la información de gnu, https://gcc.gnu.org/projects/cxx-status.html#cxx11 , gcc.4.8.1 fue la primera versión que admitió C ++ 11. En la línea de comandos g++ -v
pedirá a g++
que le indique su número de versión.
Si profundiza en la documentación, es posible que pueda encontrar la versión / subversión que primero admitió suficientes funciones para que su código, como se indica, se compile. Pero tal versión soportaría algunas características de C ++ 11 y no otras.
Como Windows no se distribuye con g ++, tendrá la versión que alguien (¿usted?) Haya elegido instalar. No habrá una versión predeterminada de g ++ asociada con su versión de Windows.
También puedes consultar con gdb.
-
$ g++ example.cpp -g
Compile el programa con el indicador -g para generar información de depuración -
$ gdb a.out
programa de depuración con gdb -
(gdb) b main
Ponga un punto de interrupción en main -
(gdb) run
Ejecutar programa de ejecución (se pausará en el punto de interrupción) -
(gdb) info source
Imprime algo como:
Current source file is example.cpp
Compilation directory is /home/xxx/cpp
Located in /home/xxx/cpp/example.cpp
Contains 7 lines.
Source language is c++.
Producer is GNU C++14 6.3.0 20170516 -mtune=generic -march=x86-64 -g.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
Existe el estándar usado por el compilador: Producer is GNU C++14
Si recompila su programa usando -std=c++11
(por ejemplo), gdb lo detecta: Producer is GNU C++11