技术分享——gcc、clang、msvc等编译器的区别

仅就从性能部分的错误诊断比较区别,之前见国外有相关文章,我做简单分享,但是,如果要了解区别,无妨从下文中包含的gcc和msvc阅读了解一下 。
GCC和Clang一直在彼此较劲尝试证明谁的错误诊断更好 。Clang首先在他们的“表现诊断”文章中讨论过GCC :
相关链接:
https://clang.llvm.org/diagnostics.html
彼方唱罢我登场,而后在GCC改进了自己的诊断程序后,又发布了就其性能提升后的文章,标题是“Comparison of Diagnostics between GCC and Clang”,可以看到非常直白和露骨了......
相关链接:
https://gcc.gnu.org/wiki/ClangDiagnosticsComparison
我们可以通过测试Clang 6.0.0、GCC 7.3.0中常见错误,同时通过编译器资源管理器MSVC 2017 19.10.25107来检验谁的性能更好 。需要特别说明的是GCC 8似乎已改进了某些消息,但它仍旧不能算是一个稳定的版本 。
我个人是把MSVC和Clang中的静态分析器排除在外的,因为将他们中的分析器拿来与GCC这方面的缺失做相应的比较,肯定是不公平的,由此,仅使用-Wall或/ W3,除非没有发现错误,否则我将尝试-Weverything,-Wextra -Wpedantic或/ Wall 。
 
第一轮:关于“分号”的缺失忘记分号,一直都是这样的
semicolon.c
#include <stdio.h>int main(void) {printf("Hello, world!n") // no semicolonreturn 0 // no semicolon}这是在printf语句和return语句之后的惯常会丢失的分号,类似这样一个常见的错误,应该开始意识到这个问题了吧,再如
~ $ gcc-7 -Wall semicolon.c semicolon.c: In function 'main':semicolon.c:5:5: error: expected ';' before 'return'return 0 // no semicolon^~~~~~ 
C:> cl /W3 /diagnostics:caret semicolon.csemicolon.c(5,5): error C2143: syntax error: missing ';' before 'return'return 0 // no semicolon^semicolon.c(6,1): error C2143: syntax error: missing ';' before '}'}^Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25017 for x86Copyright (C) Microsoft Corporation.All rights reserved.没错吧,
~ $ clang-6.0 -Wall semicolon.csemicolon.c:4:30: error: expected ';' after expressionprintf("Hello, world!n") // no semicolon^;semicolon.c:5:13: error: expected ';' after return statementreturn 0 // no semicolon^;2 errors generated.Clang显然是赢家,其次是MSVC 。而GCC没法识别第二个错误 。MSVC和GCC会僵硬的出现把 ';' 放在 'return'"之前的 errors,技术上这来讲,说得通,但不太聪明 。
第一轮打分:Clang: 2, GCC: 0, MSVC: 1
 
第二轮:缺花括号在函数末尾丢失花括号是另一个常见错误,尽管不如前一个常见 。
missingbrace.c
int main(void) {return 0;// no closing brace希望GCC或MSVC能够把这个问题解决了,
~ $ gcc-7 -Wall missingbrace.cmissingbrace.c: In function 'main':missingbrace.c:2:5: error: expected declaration or statement at end of inputreturn 0;^~~~~~实在糟糕透顶,
C:> cl /W3 /diagnostics:caret missingbrace.cmissingbrace.c(1): fatal error C1075: the left brace '{' was unmatched at the end of the fileint main(void) {Internal Compiler Error in Z:optcompiler-explorerwindows19.10.25017libnativebinamd64_x86cl.exe.You will be prompted to send an error report to Microsoft later.INTERNAL COMPILER ERROR in 'Z:optcompiler-explorerwindows19.10.25017libnativebinamd64_x86cl.exe'Please choose the Technical Support command on the Visual C++Help menu, or open the Technical Support help file for more informationMicrosoft (R) C/C++ Optimizing Compiler Version 19.10.25017 for x86Copyright (C) Microsoft Corporation.All rights reserved.我认为我有可能搞错了, 但是看上去MSVC崩掉了 。Microsoft系统可以的,除了崩掉MSVC再没缺点 。
~ $ clang-6.0 -Wall missingbrace.cmissingbrace.c:2:14: error: expected '}'return 0;^missingbrace.c:1:16: note: to match this '{'int main(void) {^1 error generated.仍旧,Clang收入2分.
1-2轮积分情况: Clang: 4,GCC: 0,MSVC: 2
 
第三轮:out of bounds又一个非常常见的错误,
outofbounds.c#include <stdio.h>static const int array[4] = { 1, 2, 3, 4 };int main(void) {for (int i = 0; i <= 4 /* should be < */; i++) {printf("%d ", array[i]);}return 0;}颇为有趣的是, 即使用 -Warray-bounds 或者 /Wall,Clang、MSVC都未曾搞清这点 。
但是,在使用-O2时,GCC实际上呈现出的是进行更改的正确选择!
~ $ gcc-7 -Wall -O2 outofbounds.coutofbounds.c: In function 'main':outofbounds.c:7:9: warning: iteration 4 invokes undefined behavior [-Waggressive-loop-optimizations]printf("%d ", array[i]);^~~~~~~~~~~~~~~~~~~~~~~outofbounds.c:6:5: note: within this loopfor (int i = 0; i <= 4 /* should be < */; i++) {^~~


推荐阅读