Linux 개발 프로젝트를 위한 Clang vs GCC
저는 대학생이고 프로젝트에 C를 사용하고 있습니다.GCC와 Clang에 대해 알아보았는데, Clang은 GCC보다 훨씬 사용자 친화적인 것으로 보입니다.그 결과 Linux에서 C와 C++로 개발하는데 GCC가 아닌 Clang을 사용하는 것의 장단점은 무엇인지 궁금합니다.
제 경우, 이것은 제작이 아닌 학생 수준의 프로그램에 사용됩니다.
Clang을 사용하는 경우 GDB를 사용하여 디버깅하고 GNU Make를 사용해야 합니까, 아니면 다른 디버거를 사용하여 유틸리티를 만들어야 합니까?
편집:
gcc 남자들은 gcc(아 경기)에서 진단 경험을 정말 향상시켰다.Wiki 페이지를 만들어 여기에 소개하고 있습니다.gcc 4.8은 현재 매우 뛰어난 진단 기능을 갖추고 있습니다(gcc 4.9배 컬러 지원 추가).클랭이 여전히 선두를 달리고 있지만 격차가 좁혀지고 있다.
오리지널:
학생들에게는 무조건 클랭을 추천한다.
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
class, 죠?? :)
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>]
그리고 클랭도 정확히 여기 출연하지는 않지만, 여전히:
/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.
전형적인 '오 마이 갓 클랭이 내 마음을 읽는다'가 아니라 불분명한 오류 메시지(문법의 모호함에서 오는)를 유발하는 예를 일부러 선택한다.그러나 Clang은 오류의 홍수를 피할 수 있다는 것을 알 수 있습니다.학생들을 겁주어 쫓아낼 필요는 없다.
두 가지 모두 사용하는데, 그 이유는 두 가지 모두 다른 유용한 오류 메시지를 주기 때문입니다.
Python 프로젝트는 핵심 개발자 중 한 명이 처음으로 clang으로 컴파일을 시도했을 때 많은 작은 버글렛을 찾아 수정할 수 있었다.
현시점에서는 GCC는 Clang보다 C++11 기능이 훨씬 뛰어나고 완벽하게 지원되고 있습니다.또한, GCC용 코드 생성기는 Clang의 코드 생성기보다 더 나은 최적화를 수행합니다(내 경험상, 나는 어떠한 철저한 테스트도 보지 못했습니다).
한편 Clang은 GCC보다 더 빠르게 코드를 컴파일하고 코드에 문제가 있을 때 더 나은 오류 메시지를 생성하는 경우가 많습니다.
어떤 것을 사용할지는 당신에게 중요한 것이 무엇이냐에 따라 결정됩니다.컴파일 편의성보다 C++11 지원 및 코드 생성 품질을 중시합니다.그래서 저는 GCC를 사용합니다.당신에게는 다른 단점이 있을 수 있습니다.
Clang과 GCC를 모두 사용하고 있기 때문에 Clang에는 유용한 경고가 몇 가지 있습니다만, 제 자신의 레이트레이싱 벤치마크에서는 GCC보다 일관되게 5~15% 느립니다(물론 염분 처리지만, 양쪽 모두에 같은 최적화 플래그를 사용하려고 했습니다).
그래서 지금은 Clang 정적 분석과 복잡한 매크로를 사용한 경고를 사용합니다(GCC의 경고는 gcc4.8~4.9와 거의 비슷합니다).
몇 가지 고려 사항:
- Clang은 OpenMP를 지원하지 않습니다.그것을 이용하는 것만이 문제가 됩니다만, 저는 그렇게 하고 있기 때문에 한계가 있습니다.(*****)
- 크로스 컴파일은 그다지 지원되지 않을 수 있습니다(FreeB).예를 들어 SD 10은 ARM에 GCC4.x를 사용하고 있습니다.예를 들어 Linux에서는 gcc-mingw를 사용할 수 있습니다.(YMMV).
- 일부 IDE는 Clangs 출력 해석을 아직 지원하지 않습니다(
예를 들어 Qt Creator - GCC의 일부 측면은 더 잘 문서화되어 있으며, GCC는 더 오래 사용되었으며 널리 사용되고 있기 때문에 경고/오류 메시지에 대한 도움을 받는 것이 더 쉬울 수 있습니다.
***** - 이들 영역은 현재 개발 중이며 조만간 지원될 예정입니다.
학생 수준의 프로그램의 경우 Clang은 기본적으로 더 엄격한 C 표준이라는 장점이 있습니다.예를 들어 다음 K&R 버전의 Hello World는 GCC에 의해 경고 없이 허용되지만 Clang에 의해 거부되어 매우 알기 쉬운 오류 메시지가 나타납니다.
main()
{
puts("Hello, world!");
}
GCC를 해야 .-Werror
이 프로그램이 유효한 C89 프로그램이 아니라는 점을 확실히 하기 위해서입니다.이 에도 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,c99
★★★★★★★★★★★★★★★★★」gcc -std=c99
C99 c c c c c c c c c c c c c 。
쨍그랑 소리가 대안이 될 수 있을 것 같아요.
은 GCC와 clang의 .a+++++a
gcc를 사용하는 을 사용하는
GCC가 표준이 되었고, 쨍그랑 소리가 대안이 될 수 있습니다.왜냐하면 GCC는 매우 안정적이고 clang은 아직 개발 중이기 때문입니다.
언급URL : https://stackoverflow.com/questions/8205858/clang-vs-gcc-for-my-linux-development-project
'programing' 카테고리의 다른 글
nuxt.js 스토어에서 플러그인에 액세스하는 방법 (0) | 2022.07.03 |
---|---|
기본/빌트인 앱을 사용하지 않고 JavaMail API를 사용하여 Android에서 이메일 보내기 (0) | 2022.07.03 |
Java Result 결과가 있는지 확인하는 방법을 설정합니다. (0) | 2022.07.03 |
Collections.emptyList()와 새 인스턴스 비교 (0) | 2022.07.03 |
사용하지 않는 기능은 최적화됩니까? (0) | 2022.07.03 |