有沒有在 UB 和 ID 上處處和「習慣認知」不同的 C/C++ 編譯器?
01-15
ub = undefined behavior
id = implementation defined對於很多問題,其實一句ub或id就可以回答,但是經常看到有人拿常見實現來反駁,比如他說int轉char就是截取最後8bit(實際上這個問題涉及好幾個id),比如他說有符號數溢出就是拋棄最高位(實際上是ub),比如他說一個類的屬性是從前往後排列(實際上不同訪問許可權的屬性的相對位置是unspecified)問題就在於,很多時候持這種觀點的人很容易找論據來振振有詞,而明知他是錯的的人,又在很多不明真相的吃瓜群主面前難以找到反例反駁
如果有一個編譯器,對於這些情況都採用比較特殊的處理,但整體又是一個合法的編譯器,拿來舉例的說服力會強一些吧
signed integer overflow有一個gcc就能實現的簡單例子
#include &
#include &
int main()
{
int32_t test = 0x7fffffff;
if (test+1 &> test) {
printf("Hello!
");
}
return 0;
}
這個例子如果test+1 wrap了,應該是一個大負數。
這段程序用gcc(在4.8.4測試)編譯,在-O0和-O1的時候不print,也就是變成了0x80000000。然而在-O2和-O3的時候,是print的,應該是直接默認test+1永遠大於test,直接扔掉了test的計算。
沒用的,這種人是不知道什麼是標準的,你和他說標準,他會和你說編譯器的實現不完全標準。你和他說實現,他就用他知道的結果來反駁你了。我最近在寫一個C語言子集的編譯器,編譯到一個Mips彙編的子集,而Mips對於有符號運算溢出是會觸發cpu中斷的
來人吶,上那個ub就能打遊戲的編譯器!
為什麼要費力氣開發這種產品呢?
應該沒有。如果一個編譯器處處都故意違反事實標準,結果就是它只能是一個玩具,無法實用。
C/C++ 標準里存在大量的未定義行為和實現定義行為,充分體現了標準委員會充滿不食人間煙火的老頑固。這些規定在二十八年前也許有一些道理,其中大部分放在今天除了人為製造問題以外沒有好處。C++ 委員會近幾年一直有人在提案減少 ud、id、unspecified,也已經取得了一些初步成績,例如 C++17 開始將保證 cout &<&< f() &<&< g() 裡面 f() 必須先於 g() 調用。(C 就不指望了,其標準委員會異常頑固。)推薦閱讀:
※如何將lisp/scheme翻譯成llvm IR,並通過llvm生成機器碼?
※linux下編程,定義數組一多就會崩潰,如何解決?
※(截止2014.8.21)windows平台上完成一個編譯器(詞法、語法分析),想使用C++11開發,有啥好的技術推薦嗎?
※這是OS X下g++的bug嗎?
※遞歸下降的語法分析程序如何進行錯誤恢復?