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

不过,GCC在这里只得到一点,因为它并不总是显示此错误 。
1-3轮积分情况: clang:4,GCC:1,MSVC:2
 
第四轮: ifs 无花括号ifs没有花括号,尽管它们显得很方便,但带来的危害往往大于弊端,例如恶名远扬的goto失败漏洞:
相关链接:
https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-goto-fail-Apples-ssl-bug-explained-plus-an-unofficial-patch/
if-else-bug.c
#include <stdio.h>int main(int argc, char**argv) {if (argc > 1) // needs bracesargc--;argv++;elseprintf("Usage: %s <arguments>n", *argv); // (this would theoretically be UB because of the argv++)return 0;}自然地作为Apple的编译器,Clang是应该意识到这个错误的,
~ $ clang-6.0 -Wall if-else-bug.cif-else-bug.c:8:5: error: expected expressionelse^1 error generated.……这是一个非常无用的错误,也难怪苹果没有发现 。
C:> cl /W3 /diagnostics:caret if-else-bug.c(7): error C2181: illegal else without matching ifelse^Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25017 for x86Copyright (C) Microsoft Corporation.All rights reserved.MSVC呈现的至少是有意义的,完全不像clang搞出些垃圾来 。
~ $ gcc-7 -Wall if-else-bug.cif-else-bug.c: In function 'main':if-else-bug.c:5:5: warning: this 'if' clause does not guard... [-Wmisleading-indentation]if (argc > 1) // needs braces^~if-else-bug.c:7:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'argv++;^~~~if-else-bug.c:8:5: error: 'else' without a previous 'if'else^~~~没想到,GCC有次一次鹤立鸡群了下,
1-4轮积分情况: Clang: 4,GCC: 3,MSVC: 2
 
第五轮:JAVA风格的字符串连接Java、JavaScript、C ++(一定程度上)和其他几种语言使你可以使用'+'来连接字符串和其他内容 。C并没有达到你的期望 。
字符串concat.c
#include <stdio.h>int main(void) {int value = https://www.isolves.com/it/cxkf/bk/2021-03-22/4;const char *string = "value = " + value; // This isn't Java!printf("%sn", string);return 0;} 
~ $ gcc-7 -Wall -Wextra -pedantic string-concat.c~ $ clang-6.0 -Wall string-concat.cstring-concat.c:5:37: warning: adding 'int' to a string does not append to the string [-Wstring-plus-int]const char *string = "value = https://www.isolves.com/it/cxkf/bk/2021-03-22/" + value; // This isn't Java!~~~~~~~~~~~^~~~~~~string-concat.c:5:37: note: use array indexing to silence this warningconst char *string = "value = " + value; // This isn't Java!^&[]1 warning generated.GCC和MSVC 在这件事上完全没搞定,而clang给出了一个有用的报错.
1-5轮积分情况:Clang: 6,GCC: 3, MSVC: 2
 
第六轮:忘记返回值有时,你忘记了一个函数需要返回一个值,或者忘记在这个switch语句之后放置一个return语句,或者还有其它种种,
no-return.c
no-return.c
#include <stdlib.h>int doesNotReturnAValue(void) {// no return value}int mightNotReturnAValue(void) {if (rand() % 2 == 0) {return 2;}// if rand() is odd, there is no return value} 
~ $ gcc-7 -Wall no-return.cno-return.c: In function 'doesNotReturnAValue':no-return.c:5:1: warning: control reaches end of non-void function [-Wreturn-type] } ^no-return.c: In function 'mightNotReturnAValue':no-return.c:12:1: warning: control reaches end of non-void function [-Wreturn-type] } ^~ $ clang-6.0 -Wall no-return.cno-return.c:5:1: warning: control reaches end of non-void function [-Wreturn-type]}^no-return.c:12:1: warning: control may reach end of non-void function [-Wreturn-type]}^2 warnings generated.啊,0分,完全没价值
C:> cl /W3 /diagnostics:caret no-return.cno-return.c(5) : warning C4716: 'doesNotReturnAValue': must return a valueno-return.c(12) : warning C4715: 'mightNotReturnAValue': not all control paths return a valueMicrosoft (R) C/C++ Optimizing Compiler Version 19.10.25017 for x86Copyright (C) Microsoft Corporation.All rights reserved.MSVC做到了 。
1-6轮积分情况:Clang: 6,GCC: 3,MSVC: 4
 
第七轮:忘记命名空间是时候来一些C ++了!
我经常犯的错误包括,忘记添加“使用命名空间”或是在调用之前放置命名空间 。
no-namespace.cpp
#include <IOStream>int main() {cout << "Hello, world!n"; // should be std::coutreturn 0;}让我们看看编辑器怎么呈现
C:> cl /W3 /diagnostics:caret no-namespace.cppno-namespace.cpp(4): error C2065: 'cout': undeclared identifiercout << "Hello, world!n"; // should be std::cout^Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25017 for x86Copyright (C) Microsoft Corporation.All rights reserved.


推荐阅读