para - compile c++ visual studio code windows
Clang vs GCC para mi proyecto de desarrollo de Linux (6)
Estoy en la universidad, y para un proyecto estamos usando C. Hemos explorado GCC y Clang, y Clang parece ser mucho más amigable que GCC. Como resultado, me pregunto cuáles son las ventajas o desventajas de usar clang, a diferencia de GCC, para desarrollar en C y C ++ en Linux.
En mi caso, esto se usaría para programas a nivel de estudiante, no de producción.
Si uso Clang, ¿debo depurar con GDB y usar GNU Make, o usar otro depurador y hacer la utilidad?
A partir de ahora, GCC tiene un soporte mucho mejor y más completo para las características de C ++ 11 que Clang. Además, el generador de código para GCC realiza una mejor optimización que la de Clang (en mi experiencia, no he visto ninguna prueba exhaustiva).
Por otro lado, Clang a menudo compila el código más rápidamente que GCC y produce mejores mensajes de error cuando hay algún problema con el código.
La elección de cuál usar realmente depende de qué cosas son importantes para usted. Valoro la compatibilidad con C ++ 11 y la calidad de generación de código más de lo que valoro la conveniencia de la compilación. Debido a esto, uso GCC. Para ti, las compensaciones podrían ser diferentes.
Creo que clang podría ser una alternativa.
GCC y clang tienen algunas diferencias en expresiones como a+++++a
, y tengo muchas respuestas diferentes con mi compañero que usa clang en Mac mientras uso gcc.
GCC se ha convertido en el estándar, y clang podría ser una alternativa. Porque GCC es muy estable y el clang aún está en desarrollo.
Para los programas a nivel de estudiante, Clang tiene el beneficio de que es, por defecto, más estricto. el estándar C Por ejemplo, la siguiente versión de K & R de Hello World es aceptada sin previo aviso por GCC, pero Clang la rechaza con algunos mensajes de error bastante descriptivos:
main()
{
puts("Hello, world!");
}
Con GCC, tienes que darle el " -Werror
para que realmente haga -Werror
en que este no es un programa C89 válido. Además, aún necesita usar c99
o gcc -std=c99
para obtener el idioma C99.
Utilizo tanto Clang como GCC, encuentro que Clang tiene algunas advertencias útiles, pero para mis propios puntos de referencia de rastreo de rayos: es consistentemente 5-15% más lento que GCC (tómelo con mofa, por supuesto, pero intentó usar indicadores de optimización similares) para ambos).
Así que por ahora uso el análisis estático de Clang y sus advertencias con macros complejas: (aunque ahora las advertencias de GCC son bastante buenas, gcc4.8 - 4.9).
Algunas consideraciones:
- Clang no tiene soporte OpenMP, solo importa si se aprovecha de eso, pero como yo lo hago, es una limitación para mí. (*****)
- La compilación cruzada puede no ser tan bien soportada (FreeBSD 10, por ejemplo, todavía usa GCC4.x para ARM), gcc-mingw, por ejemplo, está disponible en Linux ... (YMMV).
- Algunos IDE todavía no admiten el análisis de la salida de
Clangs(QtCreator, por ejemplo,*****). EDITAR: QtCreator ahora es compatible con la salida de Clang - Algunos aspectos de GCC están mejor documentados y, dado que GCC ha existido por más tiempo y es ampliamente utilizado, es posible que le resulte más fácil obtener ayuda con advertencias / mensajes de error.
***** - estas áreas están en desarrollo activo y pronto podrán ser compatibles
Yo uso ambos porque a veces dan mensajes de error diferentes y útiles.
El proyecto Python fue capaz de encontrar y corregir una serie de pequeños errores cuando uno de los principales desarrolladores primero intentó compilar con clang.
EDITAR:
Los chicos de gcc realmente mejoraron la experiencia de diagnóstico en gcc (ah competition). Crearon una página wiki para mostrarla here . gcc 4.8 ahora también tiene diagnósticos bastante buenos (compatibilidad de color de 4.9x gcc). Clang sigue a la cabeza, pero la brecha se está cerrando.
Original:
Para los estudiantes, recomendaría incondicionalmente a Clang.
El rendimiento en términos de código generado entre gcc y Clang ahora no está claro (aunque creo que gcc 4.7 todavía tiene la ventaja, no he visto puntos de referencia concluyentes todavía), pero para los estudiantes aprender realmente no importa de todos modos.
Por otro lado, los diagnósticos extremadamente claros de Clang son definitivamente más fáciles de interpretar para los principiantes.
Considera este simple fragmento:
#include <string>
#include <iostream>
struct Student {
std::string surname;
std::string givenname;
}
std::ostream& operator<<(std::ostream& out, Student const& s) {
return out << "{" << s.surname << ", " << s.givenname << "}";
}
int main() {
Student me = { "Doe", "John" };
std::cout << me << "/n";
}
Notarás de inmediato que falta el punto y coma después de la definición de la clase Student
, derecha :)?
Bueno, gcc lo nota también , después de una moda:
prog.cpp:9: error: expected initializer before ‘&’ token
prog.cpp: In function ‘int main()’:
prog.cpp:15: error: no match for ‘operator<<’ in ‘std::cout << me’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:112: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& (*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:121: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT, _Traits>& (*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:131: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:169: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:173: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:177: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:97: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:184: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:111: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:195: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:204: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:208: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:213: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:217: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:225: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:229: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:125: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]
Y Clang no está exactamente protagonizando aquí tampoco, pero aún así:
/tmp/webcompile/_25327_1.cc:9:6: error: redefinition of ''ostream'' as different kind of symbol
std::ostream& operator<<(std::ostream& out, Student const& s) {
^
In file included from /tmp/webcompile/_25327_1.cc:1:
In file included from /usr/include/c++/4.3/string:49:
In file included from /usr/include/c++/4.3/bits/localefwd.h:47:
/usr/include/c++/4.3/iosfwd:134:33: note: previous definition is here
typedef basic_ostream<char> ostream; ///< @isiosfwd
^
/tmp/webcompile/_25327_1.cc:9:13: error: expected '';'' after top level declarator
std::ostream& operator<<(std::ostream& out, Student const& s) {
^
;
2 errors generated.
Escogí a propósito un ejemplo que desencadena un mensaje de error poco claro (que proviene de una ambigüedad en la gramática) en lugar de los ejemplos típicos de "Dios mío, Dios mío, lee mi mente". Aún así, notamos que Clang evita la avalancha de errores. No es necesario asustar a los estudiantes.