Re: [問題] 一個簡單的const問題

看板C_and_CPP (C/C++)作者 (小西風最乖了*^^*)時間15年前 (2011/07/05 17:03), 編輯推噓6(6022)
留言28則, 8人參與, 最新討論串3/4 (看更多)
※ 引述《littleshan (我要加入劍道社!)》之銘言: : 試圖寫入常數是 undefined behavior : 上述的 code 在 C++ 中甚至直接視為 compile error 如同各位大大指出,C99/C++03 中試圖寫入 const 的東西(object)都是 未定義行為(除了 C++ 中的 mutable)[1]. 在此想要多補充「未定義」的意 思:一個程式一旦含有「未定義的行為」,整個程式都沒有規定,而不是執行 到某行後程式才突然當掉或是有不可預期的結果。例如: | #include <stdio.h> | int main () { | int i = 0; | printf("debug\n"); | i = (i++) + (++i); /* undefined */ | return 0; | } 不代表會印出 debug 後才「出錯」,而是整個程式打從開始就沒有意義! 我想大家都知道未定義行為要避免,但可能沒有意識到會影響到「整個」程式。 如同其他大大指出,就算編譯後的程式,連 debug 都沒有印出來就開始格式化 你的硬碟,也完全正確。 之前發現兩篇有趣的 blog 文章給有興趣的人參考: http://blog.regehr.org/archives/213 http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html (第二篇簡直就是 LLVM 開發者的抱怨文 xD) : 推 XYX16888:我只是在做測試 故意寫錯 然後了解整個過程 二樓說的太 07/05 14:37 : → XYX16888:嚴重了吧@@ 07/05 14:37 也許別的語言可以,但可惜這種測試方法對 C/C++ 完全行不通。如果你 想了解「理論上」的行為,那麼只要有未定義行為,整個程式都不用討論了。 如果你想了解「真實」的編譯器到底會吐出什麼機械碼,恐怕請編譯器吐出組 語來比較快。現在常見的編譯器會用各種方法分析並改寫你的程式,希望能提 昇效能(也就是所謂的最佳化)。常常最後產生的程式,並不會真的依照你寫 的程式一步一步執行;編譯器只要讓正確的程式「看得到」的行為是對的就好, 無論用多難以想像的方法實作都沒有關係。所以我說,請編譯器吐出組語比較 快。希望這有回答到你的問題。 就我所知 Xcode 裡面用 gcc. 加上 -S 的參數應該可以輸出組語。可能 要請用 Xcode 的人更正我 xD [1] 條文見 C99 6.7.3 和 C++98 7.1.5.1 我不想再貼條文了 xD -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.30.39

07/05 17:33, , 1F
怎麼說呢?有時候未定意行為出現在兩個因素在.1.為了速度
07/05 17:33, 1F

07/05 17:35, , 2F
因此很多細節部分,不會額外幫你處理,因為還要幫你花時間
07/05 17:35, 2F

07/05 17:38, , 3F
檢查.2.歷史的問題,10年前有些規範還未訂好或技術還不到
07/05 17:38, 3F

07/05 17:39, , 4F
但是很多系統是以前延用到現在,c/c++標準委員會因此只
07/05 17:39, 4F

07/05 17:41, , 5F
能口頭勸導你不要這樣用.如果知道是UB時.個人心態是
07/05 17:41, 5F

07/05 17:41, , 6F
賺到了,趕快記下來,以後不要犯.因為當一個專案到10萬行
07/05 17:41, 6F

07/05 17:42, , 7F
要維護時,往往讓你爆肝就是魔鬼行為害的.
07/05 17:42, 7F

07/05 17:45, , 8F
樓上好像很有切身之痛........XD
07/05 17:45, 8F

07/05 17:48, , 9F
我只有不知道UB.行為才會犯到,我比較大的切身之痛是
07/05 17:48, 9F

07/05 17:48, , 10F
模組化和撰寫前未詳細理解要解決的問題,因此寫出不知道y
07/05 17:48, 10F

07/05 17:49, , 11F
輸出是對的程式.所以我對良好程式習慣很重視.我是走安全
07/05 17:49, 11F

07/05 17:50, , 12F
路線的設計者,跟個性有關連吧
07/05 17:50, 12F

07/05 20:16, , 13F
我有問題! 那const是拿來做什麼用的@@"
07/05 20:16, 13F

07/05 20:17, , 14F
日前的訓練告訴我const是防止自己不小心改了不能被改
07/05 20:17, 14F

07/05 20:18, , 15F
的變數 如果不小心改了const 編譯時會被警告或不過
07/05 20:18, 15F

07/05 20:19, , 16F
如果沒有這個好處在變數前加上const還有其他好處嗎?
07/05 20:19, 16F
如果你是指原原 PO 的例子,「正常」的編譯器應該都會警告你。然後 C++ 除非特別用轉型否則編譯器是要叫一下的(兩個語言對 const 的態度不 同)。也就是說 C++ 要特別寫下面這種程式碼,才能讓編譯器閉嘴: | const int var = 10; | int *vptr = const_cast<int*>(&var); 然後,請盡量不要仰賴編譯器會好心警告你。尤其 C 的精神前兩條是: | 1. Trust the programmer. | 2. Don't prevent the programmer from doing what needs to be done. | ... @ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1250.pdf 簡單來說,C 程式設計師是完全被信任的 :P 用 const 更像是對編譯器 發誓你絕對不會在初始化後改它。我不確定 C++ 對於 const 的態度該怎麼 用一句話總結 xD 有待高手補完。

07/05 20:35, , 17F
compiler可以利用常數性質進行最佳化
07/05 20:35, 17F
差不多是這樣...。

07/05 20:58, , 18F
我有問題,littleshan可以舉個小例子嗎?不然這句好抽象
07/05 20:58, 18F

07/05 20:59, , 19F
不就是上一篇文章講的嗎?
07/05 20:59, 19F

07/05 20:59, , 20F
printf("%d", var); 可以變成 printf("%d", 10);
07/05 20:59, 20F

07/05 21:00, , 21F
反正var不會變,這樣就不需要去讀取var的值了
07/05 21:00, 21F

07/05 21:14, , 22F
謝謝
07/05 21:14, 22F
※ 編輯: Favonia 來自: 140.112.30.39 (07/05 21:48)

07/05 21:32, , 23F
理解!謝謝~
07/05 21:32, 23F
再補一下,如果你是說這種: | const int x = 3; | x = 4; 所有正確的編譯器都要發出錯誤訊息!這點不用擔心!

07/05 21:58, , 24F
JAVA 沒有 C++ 這樣的 const 概念,所以對於 const 就當作
07/05 21:58, 24F

07/05 21:58, , 25F
有點用處,但也不是非用不可的東西就好了
07/05 21:58, 25F
Java 有 final, 某種程度上有點類似 const, 但意思不同(也有不同的 陷阱 orz)... 為了不離題我就不多講了 xDD

07/05 22:07, , 26F
const也是介面規範之一
07/05 22:07, 26F
嗯... 補充一下,C++ 的 const 還會影響到初始化 xD(功力不夠不知 道怎樣一言以蔽之 orz) ※ 編輯: Favonia 來自: 140.112.30.39 (07/05 22:43)

07/05 23:16, , 27F
也推:)
07/05 23:16, 27F

07/06 08:57, , 28F
說起 Java final vs const 的話, Java 版我有回過一篇
07/06 08:57, 28F
※ 編輯: Favonia 來自: 140.112.30.39 (07/30 10:30)
文章代碼(AID): #1E4jDnZN (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1E4jDnZN (C_and_CPP)