190 votes

Clang vs GCC pour mon projet de développement de Linux

Je suis au Collège, et pour un projet, nous utilisons C. Nous avons exploré GCC et Clang et Clang semble être beaucoup plus convivial que GCC. En conséquence, je me demande ce que les avantages ou les inconvénients sont à utiliser clang, par opposition à GCC, pour développer en C et C++ sous Linux ?

Dans mon cas cela servirait pour des programmes de niveau étudiant, pas de production.

Si j’utilise Clang, devrais-je débogage avec GDB et utiliser GNU Make, ou utiliser un autre débogueur et faire utilité ?

135voto

Matthieu M. Points 101624

EDIT:

La gcc gars ont vraiment permis d'améliorer le diagnostic de l'expérience dans gcc (ah la concurrence). Ils ont créé une page wiki de le montrer ici. gcc 4.8 a maintenant assez de bons diagnostics (mais pas de couleurs encore, disponibles dans de 4,9 x). Clang est toujours en tête, mais l'écart tend à se réduire.


Origine:

Pour les étudiants, je unconditionnally recommander Clang.

Les performances en termes de code généré entre gcc et Clang est maintenant difficile (même si je pense que gcc 4.7 a encore de l'avance, je n'ai pas vu de concluant repères encore), mais pour les étudiants d'apprendre qu'il n'a pas vraiment d'importance de toute façon.

D'autre part, Bruit extrêmement clair diagnostics sont certainement plus faciles pour les débutants à interpréter.

Considérons ce simple extrait:

#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";
}

Vous remarquerez tout de suite que le point-virgule est manquant après la définition de l' Student classe, non :) ?

Eh bien, gcc avis de trop, après un défilé de mode:

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>]

Et Clang n'est pas exactement mettant en vedette ici, soit, mais encore:

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

J'ai délibérément choisir un exemple qui déclenche un message d'erreur confus (venant de l'ambiguïté dans la grammaire) plutôt que l'habituel "Oh mon dieu Clang read my mind" des exemples. Néanmoins, nous pouvons remarquer que Clang éviter le déluge d'erreurs. Pas besoin d'effrayer les élèves.

37voto

Mankarse Points 22800

À partir de maintenant, la GCC a beaucoup mieux et plus complet support de C++11 de fonctionnalités que Clang. Aussi, le générateur de code pour GCC effectue meilleure optimisation que celui Clang (dans mon expérience, je n'ai vu aucun des tests exhaustifs).

D'autre part, Clang souvent compile le code plus rapidement que GCC, et produit de meilleurs messages d'erreur quand il ya quelque chose de mal avec votre code.

Le choix de celui à utiliser dépend vraiment de ce que les choses sont importantes pour vous. J'ai de la valeur de C++11) de support de génération de code et de qualité plus que je ne l'apprécient la commodité de la compilation. De ce fait, j'utilise GCC. Pour vous, le compromis pourrait être différent.

26voto

Raymond Hettinger Points 50330

J’ai utiliser à la fois parce qu’ils donnent parfois des messages d’erreur différents, utile.

Le projet de Python a été capable de trouver et de corriger un certain nombre de petites buglets lors de l’un des développeurs du noyau d’abord essayé de compiler avec clang.

8voto

larsmans Points 167484

Pour les étudiants des programmes de niveau, Clang a l'avantage qu'il est, par défaut, les plus strictes de wrt. le C standard. Par exemple, le K&R, dans la version de Bonjour tout le Monde est accepté sans avertissement par GCC, mais rejeté par Clang avec quelques jolies descriptif des messages d'erreur:

main()
{
    puts("Hello, world!");
}

Avec GCC, vous devez donner -Werror pour l'obtenir, il à vraiment faire un point sur ce qui n'est pas valide C89 programme. Aussi, vous devez toujours utiliser c99 ou gcc -std=c99 pour obtenir le C99 langue.

7voto

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X