C_and_CPP 板


LINE

※ 引述《wtchen (沒有存在感的人)》之銘言: : 以下是板工的小小心得,準備補充13誡用。 : 若是有不對的地方,請各位鞭小力點 /(_ _)\ : (板工很懶得上色,以後會放一份在板工新blog) 你已經懂得查資料和規格書了,所以這次回文就不提規格書。 我把回文重點放在其它地方。 : ### 在C的情況(注意:C++不適用,C++的場合請看下一節) ### : 根據C11 standard 6.3.2.3 裡對空指標常數 (null pointer constant)的定義: : An integer constant expression with the value 0, or such an expression cast : to type void *, is called a null pointer constant. : 也就是說,(void*)0 是空指標常數(null pointer constant), : 而(int *)0 是型別為整數指標的空指標(null pointer),這兩者是不一樣的。 : 比較明顯的分別是,空指標常數可以被設成任何型別指標的左值, : 而空指標只能被設成同樣型別指標的左值。 : 以下是一個比較清楚的例子: : int *a = 0; // 沒問題,空指標常數 : int *b = (int*) 0; // 沒問題,左值是同型別的空指標 : int *c = (void*) 0; // C沒問題,左值是空指標常數,不過C++會掛 : int *d = (long*) 0; // 爆了,左值跟右值不同型態 上面這行在 C 不會爆炸,這也是 C 之所以被 C++ 爸爸討厭的原因之一。 C 本身對這種不相容指標是相當寬容的,只會給你 warning 而已。 clang 3.4.1: warning: incompatible pointer types initializing 'int *' with an expression of type 'long *' gcc 5.1.0: warning: initialization from incompatible pointer type 這種警告訊息就算不打開 -Wall 都一樣會跳出來,目的是提醒這寫法可能有問題。 在開發階段使用 -Wall -Werror 將警告訊息全部修掉,是軟體工程師該有的態度。 因為 -Werror 會將 warning 變成 error,因此每個 warning 都逃不掉。 只是因為 warning 這東西很看 compiler 跟版本,所以 release 出去會拿掉 -Werror。 畢竟有些 compiler 會實驗一些比較新的警告功能,然後就會產生誤報。 有些使用者會使用更嚴格的 compiler,會產生 warning 的條件更多,所以不能留著。 但是在開發期間,這個選項還是該被打開,這是避免程式出錯的最基本原則之一。 另外,左值 (lvalue) 和右值 (rvalue) 是有既定成俗的中英對照。 你這邊想表達的是 LHS 跟 RHS,使用左值和右值是不恰當的。 : 這邊有另一個例子: : typedef void (*func)(void); // func f = void (*f)(); : func a = 0; // 沒事,a是空指標常數 : func b = (void *)0; // C 沒問題,C++會掛 : func c = (void *)(void *)0; // C跟C++都看不懂 : ### 在C++的情況 ### : 根據C++14 standard 4.10 裡對空指標常數 (null pointer constant)的定義: : A null pointer constant is an integer literal (2.13.2) with value zero : **or**(以後為C++11後特有) a prvalue of type std::nullptr_t. : 意思是說,它可以是0或 nullptr,所以以下的情況: : int x = NULL; // C++ 可能沒問題(視版本而定),不過會造成誤解 可能沒問題就是有問題的,你應該明確地叫大家不要這樣寫。 就像你貼的規格書定義,它在不同的 compiler 有不同的可能性。 因此這行丟到 gcc 和 clang 去開 C++11 mode 就會爆炸了。 clang 3.4.1: error: cannot initialize a variable of type 'int' with an rvalue of type 'nullptr_t' gcc 5.1.0: error: cannot convert 'std::nullptr_t' to 'int' in initialization 我在用 C++11 模式編譯數百個 open source 專案的過程裡,這算是常踩到的錯誤之一。 所以我對這種寫法超級不爽,原本不該寫在 C++ 的東西就不該出現,沒有寬容的餘地。 實際上這在 C++11 以前也是不好的 code。 因為就算不用 C++11 mode,即使不開 -Wall 也會有警告訊息。 clang 3.4.1: warning: implicit conversion of NULL constant to 'int' gcc 5.1.0: warning: converting to non-pointer type 'int' from NULL : int* ptr = (void*)0; // C 沒問題,C++會掛 : int* ptr = nullptr; // C++11以後的正統用法, : 也就是上述C++14 standard裡的空指標常數 : **int x = NULL** 為啥會在C++裡造成誤解? : 因為C++有C沒有的函數重載(function overloading),舉例來說 : void DoSomething(int x); : void DoSomething(char* x); : - NULL = 0: DoSomething(NULL)會呼叫void DoSomething(int x),即 : DoSomething(0)。 : - NULL=nullptr: 會呼叫void DoSomething(char* x),即DoSomething(nullptr)。 : 結論就是,C++11以後還是儘量用nullptr取代NULL吧! 事實上在 C++11 以前,C++ 的爸爸就很不喜歡使用 NULL: http://www.stroustrup.com/bs_faq2.html#null C++ 的爸爸很早之前就叫大家直接在 C++ 寫 0 代表空指標,而不是寫成 NULL。 因此用 0 取代 NULL 這件事是要對從 C 轉到 C++11 以前的人說的。 用 nullptr 取代 0 則是要對習慣舊 C++ 標準要轉到 C++11 以後標準的人說的。 這個拆成兩部分來說明會比較好。 : ### 參考資料 ### : - [comp.lang.c FAQ list · Question 5.2 ](http://c-faq.com/null/null2.html) : - [Is (int *)0 a null pointer?] : (http://stackoverflow.com/questions/21386995/is-int-0-a-null-pointer) : - [Why are NULL pointers defined differently in C and C++?] : (http://stackoverflow.com/questions/7016861/ : why-are-null-pointers-defined-differently-in-c-and-c) -- Ling-hua Tseng ([email protected]) Andes Technology Corporation Compiler Group of RD/Software Division Homepage: http://blog.tinlans.org --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.132.55.117
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1461824349.A.B47.html
1F:推 james732: 推 04/28 14:34
2F:推 Frozenmouse: 受教 <(_ _)> 04/28 15:08
3F:推 mabinogi805: 受教了!<(_ _)> 04/28 15:14
4F:推 BlazarArc: 推 04/28 15:15
5F:推 wtchen: 感謝,受教了!<(_ _)> 04/28 15:42
6F:推 wtchen: 已經有修改版了,請繼續鞭 /(_ _)\ 04/28 18:58
7F:推 Caesar08: 推 04/29 10:09







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Soft_Job站內搜尋

TOP