「只要是微軟的 C++,都是不標準的,而且 IDE 龐大,C++ 11 的特性都沒支持全」是真的嗎?
剛開始學,用的VC,有人如上說,推薦我用CodeBlocks。。。求知道為啥不標準?
我必須前排說一下。Cl 對於 C++ 標準支持本來就是最爛。Visual Studio 2015 修復了 750 個 Bug。750個,由此可見 2013。2013 的時候居然連類內成員初始化都是有Bug的,只能靠弄一個 Error,呵呵呵呵。。。
不符合標準就是不符合標準。Cl 不支持 C++ 98 的 Two-phase lookup,那一套 ATL的代碼都是不符合標準的,還得 Clang 用一些 hack 讓它們編譯過,呵呵呵。Cl 不支持 Expression SFINAE(目前對 Expression SFINAE 的支持為 Partial):導致各種開源代碼編譯不過(一位大神實現的 intrusive_ptr,根本在 Cl 上編譯不過。lhmouse/intrusive_ptr · GitHub ,更不用提帝球的YSLib了。)
那 Minimal Support for GC。。。我來給大家看一下 VC++ 的實現:
inline void declare_reachable(void *)
{ // increment pointer reachable count
}
template&
_Ty *undeclare_reachable(_Ty *_Ptr)
{ // decrement pointer reachable count
return (_Ptr);
}
inline void declare_no_pointers(char *, size_t)
{ // declare region to be pointer free
}
inline void undeclare_no_pointers(char *, size_t)
{ // undeclare region to be pointer free
}
inline _Pointer_safety get_pointer_safety() _NOEXCEPT
{ // get pointer safety status
return (pointer_safety::relaxed);
}
全都是 No-op 好吧(當然,標準說 No-op 是合法的)。這。。。各位自己看。
而且,Cl 到現在還不支持 Extended constexpr(C++ 14),又導致一票標準庫不符合標準。可能又要有人說沒用了?.......
這當然不是全部:
Nonstandard Behavior
再補一刀吧,The C++ Programming Language 4th Edition 中的一段代碼:
void f()
{
char* p = "Plato"; // error, but accepted in pre-C++11-standard code
p[4] = "e"; // error: assignment to const
}
然而 Cl 在/W3下無警告接受 char* p = "Plato"。(Update:有聚聚指出使用 /Zc:StrictString 可報 Error)
用 Cl 寫 C++ 非常痛苦的——你寫了一段模板,在 Clang/MinGW 下都編譯得那麼順利,而到了 Cl,就要想出各種Workaround了。
那些跟你說vc對C++11支持不完整的,你可以回敬他們,切,vc連C++98的支持都不完整好嗎。(WTF)
好吧,認真說說。
到vc14為止,也就是VS2015(昨天RTM哦昨天RTM哦昨天RTM哦),Solving the SFINAE problem for expressions (DR339)這個C++11的特性還不支持。原因在於SFINAE這個C++98特性vc一直都沒去做。不做的原因是沒卵用,二次查找還對編譯性能有影響。g++和clang都號稱達到了C++11 complete,但其實他們都不支持Minimal support for garbage collection and reachability-based leak detection (N2670),clang不支持Abandoning a process and at_quick_exit (N2440),不支持的原因也一樣是看不出有卵用。
編程語言是拿來用的,不是拿來比支持度的。第一個宣布支持完整C++98的編譯器是Comeau,真的有人用?vc雖然不支持全部功能,不過已經足夠編譯和使用C++11的代碼了,另外還比gcc/clang多了filesystem這個TS的支持,可以免於使用boost.filesystem。
IDE來說,其他的完全沒法跟vs比。
另附幾大編譯器對C++11的支持比較 C++11 support in compilers
分開來回答把:
1,只要是微軟的 C++,都是不標準的。
應該說微軟獨有的那部分擴展特性,別人沒有,(比如什麼 CString,stdafx,獨有的pragma標籤之類),你若是不用那些非標準特性,微軟仍然可以是標準的。
2,IDE 龐大。
這個顯然並沒錯,安裝 Visual Studio 必須佔用 C 盤的空間(即便設定為D盤也必須將大部分內容放在C盤),而且還不小。數倍甚至數十倍於其他 IDE 所佔用的空間。不過只要你有剩餘空間,這其實也不算是個大問題。
3,C++ 11 的特性都沒支持全。
(原評論已刪)有知友指出 clang 已經完整支持,所以這一點 clang 應該更有優勢。
4,另外我注意到樓主的用詞「VC」,這個用詞一般是用來形容 98 年的 VC6 的,現在的人用 VS 居多,所以能說出 VC 給人感覺你仍然在用上個世紀的編譯器,而如果你堅持使用上個世紀的編譯器,它離當前標準相差太遠太遠了:請回到二十一世紀。
我們看到,其實你朋友說的話基本上是對的,只是看你怎麼理解罷了。使用其他的編譯器能夠讓你避免使用微軟獨有功能的誘惑,這樣你的代碼將來就算拿到 Visual Studio 裡面也是能夠編譯的。而使用 VS 的話,新手基本上很難避免誘惑不去使用 VS 專有特性,而一旦使用這些特性,你的代碼不容易移植到其他平台,就被微軟綁定了。——對於老手來說這確實不是問題。問題在於並非所有人都是老手,所以微軟通過獨佔特性來鎖定新手程序員的行為,很有必要向新手指出。
至於輪子哥 說的「最好的編譯器是 ICC」,我表示呵呵。ICC 的存在是為了讓代碼為 intel CPU 做優化。因此,這個編譯器「好」的前提是所有代碼都在 intel 的 CPU 上運行,很幸運現在這並不是事實,移動平台已經遠遠超過了桌面PC的數量以及使用率,而他們絕大多數都不是用的 intel CPU。你要的是提升自己的編程興趣而不是在意工具這個細節,不要相信那些人說的用IDE你就不了解鏈接和預編譯的過程,只要你有心就可以去學和了解,最後用@vczh的話結束,逗逼的程序員秀工具,優秀的程序員秀的是代碼,大概就是這樣
不要聽他們胡說。這個言論是從VC6開始的。VC6的確很不標準,因為它誕生的比標準早,但是卻流行的那麼廣,於是那幫開源X就天天拿這個說事情了。VC6都已經17年前的事情了。
現在已經是VC2013了,你到了今天才問這個問題是很幸福的,到了年底就完全支持C++14的所有功能了,特別的標準。至於現在還不支持的那一小部分,因為你才剛開始學,估計是用不到的……
CodeBlocks調試起來特別痛苦,你在windows上的話,VC++2013才是最舒服的。如果你不想用盜版的話還有Express免費版用。當然CodeBlocks體積比VC++小很多,因為它功能少啊(逃
=====================================
話說我要吐槽一句,C++的字元串常量不能直接把換行寫進去,於是到了C++11,我們有了偉大的raw string。作為一個編譯器作者,在寫unittest的時候我特別喜歡用raw string來寫短小精悍的代碼來測試編譯器。好了,g++的宏裡面用了raw string就會傻逼……這跟沒有支持有什麼區別?其實都一個尿性。g++跟VC++一樣都有很多C++標準以外的東西,而且也各有不支持的特性。開源X最喜歡的就是對g++的缺點避而不談了。
作為C++愛好者,我寫的代碼充滿了很多新特性,於是爆了很多VC++和g++的bug。VC++我都直接email給同事了,然後就修了。g++的bug一開始那幾個別人發現過了,然後在bugzilla上面看到垮了很多個版本都沒修,拚命做新feature,於是後來發現的新bug我都懶得提了,提了也沒用,反正是不會修的。
g++用這種做web的態度來做編譯器,活該被clang幹掉,成為編譯器史上的一個大傻逼。
=====================================
再說一句,世界上最好的編譯器其實是intel的icc,編譯出來的C++代碼的性能最好。其次是VC++。clang的位置我不知道,最近還一直在更新,大有前途。
g++不僅編譯慢,編譯出來的代碼還有各種bug,多少人不敢開-O2,也好意思說VC++支持的不夠全面。
簡單總結一下,MSVC 14.0(就是 VS 2015 帶的,2015-07-29)完全支持了 C++11,基本有一半的特性是這個版本剛實現的。剩下的大概一半是 MSVC 12.0 實現的(2013-11-13)。C++14 的特性完全是在 MSVC 14.0 才開始支持,還沒實現完。
作為比較 clang 3.3(2013-04-19)完全實現了 C++11,clang 3.4(2013-11-06)完全實現了 C++14。gcc 4.8.1(2013-05-31)完全實現了 C++11,C++14 還沒弄完。
具體在這:C++ compiler support,自己看吧。
這樣比較下來,微軟明顯是標準支持最差的,雖然現在不太明顯,但是在 MSVC 14 發布前還是極為明顯的,也無怪乎大家形成這樣的印象,更何況廣為傳播的 VC6 早就惡名滿滿(但不是 VC6 之後的版本就沒有支持差的問題,實際上是 VS 2015 剛剛解決的,需要再強調一遍)。
clang 明顯是支持最好的,現在也是這樣,C++17(的提案)已經實現了很多。我們可以看到,微軟現在明顯加快了支持標準的步伐,我猜測是(新 CEO 帶來的?)戰略上的變化,這也是可以從其他方面看出來的。
至於 IDE 大的問題,知乎上早有許多討論,比如為什麼Microsoft Visual Studio 的安裝要佔用如此大量的C盤空間? - 編程。我的意見是,雖然 C 盤不應該出現容量問題,但是沒有必要洗地。洗地就是在打微軟的臉。如果這不是個問題,微軟也不必這樣了(微軟Connect(); 大會內容梳理:Visual Studio系列宣布):
微軟也在Connect();上展示了下一代Visual Studio的版本,新的Visual Studio將更輕量化,將會有非常靈活的安裝選項
Code::Blocks 這種爛 IDE 就免了,基本沒有分析功能,還不如用文本編輯器。IDE 推薦 CLion,或者 VS 裝 ReSharper C++。兩者是同一技術。比較耗內存(資源實在不夠就裸的 VS 好了),換來的是更好的靜態分析。自己權衡吧。
本來這個問題本身不值一答,不過不想更多的初學者對微軟開發工具產生誤解,特別針對 @Luxward 的答案說明和引申一下。在這之前,要說的是cl.exe確實C++14/17的標準特性還不全。以下都已VS2015為例。
vs 默認開啟stdafx就讓我很不爽。
stdafx.h是預編譯頭文件技術在VC中的實現,同樣採用這一技術的還有其他所有主流編譯器:Precompiled header。而且,這個是編譯優化措施,和C++標準沒有任何關係。其他編譯器都是默認打開此特性。在VC中,如果不想用這個特性,可以去掉/Yc,/Yu選項,編譯速度感人,而且不符合綠色環保潮流。重點是要用對了。
還有很多默認的開關都是逼著你用微軟私有的庫函數,比如_s函數和某些特性。
我也在和答案作者在他的答案評論里討論過了。*_s函數是非常非常推薦的原函數替代品,在性能不是非常要命的地方100%應該強制使用,更應該配合n系函數共同使用,效果最佳。原作者抱怨被強制使用(不用的話出error),是因為VC編譯器默認開啟了SDL Check,把它改為禁用(/sdl-),就沒有error了。SDL也就是Security Development Lifecycle,是微軟的一套安全軟體工程規範,有興趣的可以看http://www.microsoft.com/en-us/sdl/default.aspx
最後,關於規範。不是說編譯器自己有擴展就叫不符合規範,否則沒有編譯器是符合規範的。編譯器提供了禁用擴展的option就行。而且即便擴展擺在那裡,你不去使用它,那也等於你沒有用到非規範的東西。VC裡面,/Za選項就可以禁用擴展。
附帶列一下gcc的擴展:https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Extensions.html
P.S. 跟本題沒關係:有時候,拳頭(市場)就是真理。比如Chrome和WebKit,事實上的業界標準,HTML形式標準大家只能呵呵。Firefox,IE(Edge),Opera紛紛低頭默默支持WebKit擴展。1、微軟對C++的支持確實有缺陷。
2、IDE龐大是龐大,可你也不想想它的功能有多強大。
3、就算不用VS,也輪不到CodeBlocks。CLion、Qt Creator、VSCode、Vim+YCM表示不服。
4、雖然題主當時沒有,VS2017已經支持將代碼通過ssh放到Linux上編譯了。
這個問題你去問Google吧,因為Chrome組同時滿足「使用VisualStudio」和「C++11特性用得飛起」這兩個特徵。
https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md
對於第二點大家應該都沒什麼疑問,至於第一點,可以去看Chromium說明——Google強制你只能使用當前時間點下最新版本的Visual Studio來獲得必要的編譯工具鏈。
這幾天要寫linux代碼,但vim用著不是很習慣,所以還是在VS2013上裝了個vsvim插件碼代碼。結果在vs上編譯通過了,clang++編譯就不過。
發現問題是自己有寫的不標準的地方,dependent name需要在前面加上typename關鍵字,我沒加,結果vs太智能就給通過了。
雖然智能是好事,但不嚴格遵守標準不利於代碼移植。丫至少給我來個警告啊行不行!
要說c++11標準,所有編譯器都有一個功能沒實現,就是raw string literal的u8前綴嚴格的說,C++標準只有98、03、11、14。VS家族對標準的正確支持是從2010開始的。學C++用2010、2013絕對沒人說閑話。用vc6講課的老師大有人在……這是老師太爛的緣故。
至於夾帶私貨,各家都有,包括clang。講語言卻帶上mfc、wpf的老師也一大堆,依舊老師的問題……
只是拜託你就學個語言而已,最多跑兩三個單文件的代碼,掛上VS還要建個工程嫌不嫌麻煩啊……
Visual studio 是最好的ide,沒有之一。龐大歸龐大,但是夠強大。你說看片你是看高清的還是看640*480的?放心用就好了,剛開始學不必要關係啥支持的全不全的,細枝末節的跟你不搭嘎。另外剛開始學的話……不妨試試C#吧。。。
C++ 11 的特性幾乎沒有哪個編譯器是完美支持的。至於標不標準?
vs2015我還沒用過,vs2013來說,貌似empty base optimization還是有問題的:
struct B{};
struct C:B{
char a[4];
};
struct D:B{
C f;
};
int main()
{
std::cout&<&< sizeof B &<&< " " &<&< sizeof D; //displays : 4 5
}
你看看vs輸出的是啥。empty base optimization的相關說明找尋ISO/IEC 14882即可。
類似的vs的cl編譯器實現不完美的地方應該還有很多。不過總得來說,其對標準的支持程度還算可以。vs 默認開啟stdafx就讓我很不爽,還有很多默認的開關都是逼著你用微軟私有的庫函數,比如_s函數和某些特性。
如果不熟悉微軟的IDE的話,真拿它們沒轍。從某種意義上講,微軟就有意誤導你不使用標準c++。
雖然ms的編譯器支持標準c++,但是通過這種手段安利微軟的私貨真的好嗎?
自從微軟的市場領導地位受到開源和其他競爭對手的強有力的挑戰後,微軟的Vc比以前標準多了windows系統也開始向國際標準靠攏,廢掉了大量自己專有技術。
從lz的問題來看,是對於Windows平台來說的吧。
對於較新版本的話,兩者對C++標準的支持都不錯了,而且都都在持續增強中,這不是重點。
VS十分強大,但是我現在沒有用,原因是太強大而附帶了太多東西,太多都用不上,最蛋疼的是資料庫相關的一大堆東西;而且占空間大,機子舊了,用起來卡,特別是啟動的時候,我以前都是直接用命令行的。
CB只是一個單獨的IDE,所以如果在Windows下,還要用mingw的gcc(也可以用VS的編譯器,但是沒試過),雖然有附帶的,但是配置什麼的對新手來說也很麻煩;而且畢竟不是親媽,gcc在windows上還有一些小問題,比如scanf、printf格式化符支持等。
如果是新手,新版本的都不錯。
至於Clang,很不錯,但是不建議在windows下折騰。
--------------------最後還要說一句廢話:關鍵是人,而不是工具。
題主用的 VC6 嗎?VC6確實很不標準,請使用 2013 以上的版本。
和 VC6 比,確實 CodeBlocks 好多了。
能完全支持標準而不自帶擴展的編譯器真沒見過,不管是gcc 還是msvc,還是clang
1. g++也不標準,裡面加了自己的很多黑魔法。
2. IDE的體積和功能不可兼得。
3. 你不可能用到全部的c++11特性,為何要求編譯器支持全部的特性?貪多嚼不爛。況且98也沒有全部支持,不還用得好好的么。
4. 微軟的不標準是指http://vc.net(c++/cli)?不用不就得了,我一直將其看為另一種語言。mfc是一個三方庫,跟標準毫無關係,就像很多類似的三方庫一樣,code::blocks也自帶wxwidgets。
這些人大多都是「伊斯蘭國」式極端 Linux 粉開源粉,或者無腦果粉之類。
推薦閱讀:
※如何以「Hello World!」為腦洞如何展開一篇故事?
※怎樣使用 GitHub?
※學習編程需要安裝哪些軟體?
※C 與 C++ 誰的效率高,為什麼?
※對使用 C++ 異常處理應具有怎樣的態度?
