什麼樣的C++代碼不開O2沒事,一開O2就會出錯?

本人OI黨,用Dev C++寫程序,在OJ網站評測。在其他網站不出問題的代碼,一到BZOJ(大視野)就會RE(運行錯誤),得知是BZOJ開了O2優化所致。請問O2優化開了以後,什麼樣的代碼是會出問題的?


BZOJ 不能用 malloc、realloc、time、clock 等可能會引起某些系統調用的函數,用了就 RE。原因可能是因為 BZOJ 直接用 ptrace 封掉了所有系統調用。這個鍋 O2 不背。

另:開了 O2 會掛的一種代碼:

#include&

int main(){

int s=0;

for(int i=0;i&<200000;++i)s+=i;

printf("%d %d",s,s&<0);

}

不開 O2 輸出:-1474936480 1

開 O2 輸出:-1474936480 0

為什麼呢?編譯器想:s 初值大於等於 0,每次都加一個大於等於 0 的數,結果一定不會小於 0,那我就直接把 s&<0 優化成 0。自然溢出什麼的,反正是未定義行為,我就當它沒發生。

事實上很多代碼都會被優化 WA 或 RE,如 p[i]=(Point){nextint(),nextint()} 必掛,在幾何題中坑了我好多次。


我在本地測沒問題,bzoj(開o2)上掛掉的代碼絕大多數都是因為某些函數忘記寫return…


一般來說這肯定不是compiler的bug。

O2會對code是否遵守語法和規則有更強的要求,比如一些依靠undefined bahavior的code就很容易出錯。(out of bound memory access之類的)

之前碰到過這樣的問題。在開了O2之後程序輸出的幾個G的data裡面8個byte變成了0。

花了很長時間debug這個問題。最後發現有用到uninitialized memory,O2中的omit feame pointer導致uninitialized memory behavior不一樣了。


這還用問,當然是錯誤的代碼!


比如違背了strict aliasing


推薦閱讀:

有哪些這樣的圖片或句子?
獲得IOI金牌是怎樣的一種體驗?
ACM界的「叉姐」為什麼那麼出名?
Mathworks公司中的程序員是一群怎樣的人有著怎樣的工作體驗?
流場計算的軟體中,關於層流轉捩計算的軟體或者開源軟體有哪些?

TAG:編程 | C | OI | 信息學競賽 |