리눅스 개발 프로젝트를위한 Clang vs GCC
저는 대학에 있고 C를 사용하는 프로젝트를 위해 GCC와 Clang을 살펴 보았으며 Clang은 GCC보다 훨씬 사용자 친화적 인 것으로 보입니다. 결과적으로 Linux에서 C 및 C ++로 개발하기 위해 GCC와 달리 clang을 사용하는 이점과 단점이 무엇인지 궁금합니다.
제 경우에는 프로덕션이 아닌 학생 수준의 프로그램에 사용됩니다.
Clang을 사용하는 경우 GDB로 디버깅하고 GNU Make를 사용해야합니까, 아니면 다른 디버거를 사용하여 유틸리티를 만들어야합니까?
편집하다:
gcc 사람들은 실제로 gcc (ah 경쟁)의 진단 경험을 개선했습니다. 그들은 여기에 그것을 보여주는 위키 페이지를 만들었습니다 . gcc 4.8의 진단 기능도 향상되었습니다 (gcc 4.9x 추가 색상 지원). Clang은 여전히 선두에 있지만 격차는 좁혀지고 있습니다.
기발한:
학생들에게는 무조건 Clang을 추천합니다.
gcc와 Clang 사이에서 생성 된 코드 측면에서 성능이 명확하지 않습니다 (gcc 4.7이 여전히 선두를 가지고 있다고 생각하지만 아직 결정적인 벤치 마크를 보지는 못했습니다). 그러나 학생들이 배우는 것이 실제로 중요하지는 않습니다.
반면에 Clang의 매우 명확한 진단은 초보자가 쉽게 이해할 수 있습니다.
이 간단한 스 니펫을 고려하십시오.
#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";
}
Student
클래스 정의 후에 세미콜론이 누락되었음을 바로 알 수 있습니다 .
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>]
그리고 Clang도 여기에 정확하게 출연하지는 않지만 여전히 :
/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.
I purposefully choose an example which triggers an unclear error message (coming from an ambiguity in the grammar) rather than the typical "Oh my god Clang read my mind" examples. Still, we notice that Clang avoids the flood of errors. No need to scare students away.
As of right now, GCC has much better and more complete support for C++11 features than Clang. Also, the code generator for GCC performs better optimisation than the one in Clang (in my experience, I have not seen any exhaustive tests).
On the other hand, Clang often compiles code more quickly than GCC, and produces better error messages when there is something wrong with your code.
The choice of which one to use really depends on what things are important to you. I value C++11 support and code generation quality more than I value convenience of compilation. Because of this, I use GCC. For you, the trade-offs could be different.
I use both because sometimes they give different, useful error messages.
The Python project was able to find and fix a number of small buglets when one of the core developers first tried compiling with clang.
I use both Clang and GCC, I find Clang has some useful warnings, but for my own ray-tracing benchmarks - its consistently 5-15% slower then GCC (take that with grain of salt of course, but attempted to use similar optimization flags for both).
So for now I use Clang static analysis and its warnings with complex macros: (though now GCC's warnings are pretty much as good - gcc4.8 - 4.9).
Some considerations:
- Clang has no OpenMP support, only matters if you take advantage of that but since I do, its a limitation for me. (*****)
- Cross compilation may not be as well supported (FreeBSD 10 for example still use GCC4.x for ARM), gcc-mingw for example is available on Linux... (YMMV).
- Some IDE's don't yet support parsing Clangs output (
QtCreator for example*****). EDIT: QtCreator now supports Clang's output - Some aspects of GCC are better documented and since GCC has been around for longer and is widely used, you might find it easier to get help with warnings / error messages.
***** - these areas are in active development and may soon be supported
For student level programs, Clang has the benefit that it is, by default, stricter wrt. the C standard. For example, the following K&R version of Hello World is accepted without warning by GCC, but rejected by Clang with some pretty descriptive error messages:
main()
{
puts("Hello, world!");
}
With GCC, you have to give it -Werror
to get it to really make a point about this not being a valid C89 program. Also, you still need to use c99
or gcc -std=c99
to get the C99 language.
I think clang could be an alternative.
GCC and clang have some differences on expressions like a+++++a
, and I've got many different answers with my peer who use clang on Mac while I use gcc.
GCC has become the standard, and clang could be an alternative. Because GCC is very stable and clang is still under developing.
참고URL : https://stackoverflow.com/questions/8205858/clang-vs-gcc-for-my-linux-development-project
'Programing' 카테고리의 다른 글
웹 워커의 사용 사례는 무엇입니까? (0) | 2020.05.29 |
---|---|
'블러'이벤트가 발생하면 어떤 요소 초점이 *로 * 이동했는지 어떻게 알 수 있습니까? (0) | 2020.05.29 |
컴파일러가 일반 함수보다 람다를 더 잘 최적화 할 수있는 이유는 무엇입니까? (0) | 2020.05.29 |
Java로 LRU 캐시를 어떻게 구현 하시겠습니까? (0) | 2020.05.29 |
파이썬의 SFTP? (0) | 2020.05.29 |