2012-07-11 81 views
1

我使用PellesC C編譯器的工作。有時我的代碼會隨機停止工作。一個特定的陳述可以觸發它。例如,我用sin(c)乘以一個變量(c是一個double),我的代碼似乎剛剛結束執行而沒有結果。有時會凍結,有時似乎只是返回,但我總是可以通過刪除違規語句或禁用編譯器優化來修復它,特別是「最大化速度」或「最大化速度」。如果我在接近崩潰點附近的地方添加printf語句,凍結也將幾乎100%的時間消失。我從來沒有發現任何暗示我正在訪問內存不正確的東西,我相當確定它是一個編譯器問題。我想知道是否有人可以對此作出說明。事實上,我有可能做錯了什麼?或者這是Pelles C編譯器的一個已知問題?代碼可以停止編譯器優化

編輯:

(在最後一行的末尾差)更改

canvas->pixels[(y*canvas->pitch)+(x*canvas->Bpp)+2]=(unsigned char)(255.0*dtempA*(1-sin(c))); 
canvas->pixels[(y*canvas->pitch)+(x*canvas->Bpp)+1]=(unsigned char)(255.0*dtempA*(1+cos(c))); 
canvas->pixels[(y*canvas->pitch)+(x*canvas->Bpp)]=(unsigned char)(255.0*dtempA*(1+sin(c))); 

canvas->pixels[(y*canvas->pitch)+(x*canvas->Bpp)+2]=(unsigned char)(255.0*dtempA*(1-sin(c))); 
canvas->pixels[(y*canvas->pitch)+(x*canvas->Bpp)+1]=(unsigned char)(255.0*dtempA*(1+cos(c))); 
canvas->pixels[(y*canvas->pitch)+(x*canvas->Bpp)]=(unsigned char)(255.0*dtempA*(1+1)); 

使得它的工作。

+3

你有一個測試用例顯示? – ouah 2012-07-11 22:57:07

+1

是的,您可能會做錯某些事情,比如依賴導致未定義行爲的構造。這就是沒有[SSCCE](http://sscce.org/)可以說的一切。 – 2012-07-11 23:00:17

+0

您正在處理SIGFPE嗎? – EJP 2012-07-11 23:41:15

回答

2

你可能無意中使用未定義行爲的地方,並改變程序隨機指令是打破這種情況發生,使工作方案堆棧上的代碼非常脆弱對齊。

+0

等待...堆棧上的代碼?我認爲C只使用棧來存儲變量,傳遞參數,返回值等。爲了進一步澄清,你是否說我的程序意外地改變了用於執行代碼的內存中的字節?分配給堆棧的內存在物理上是否足夠接近可執行代碼,以便在任何合理實際的情況下發生? – 2012-07-12 23:54:05

+0

對不起,我真的很不精確。它可能改變了堆棧中的內存值,所以引用這些內存值的程序指令(IE,對堆棧指針和內容的相對引用)可能會改變。你是正確的,因爲實際的代碼沒有存儲在堆棧中,也沒有數據本身的改變 - 而是對UB程序的小改動突然讓編譯器能夠做出截然不同的事情。 – argentage 2012-07-13 04:14:35

4

它可以是,但一個不錯的選擇是,它是你:)變量沒有被明確初始化,往往會在優化VS一個未優化的建立得到不同的值,因爲棧佈局可以根據微妙地改變如何積極的編譯器會刪除臨時對象以及其他因素。

+0

我會檢查所有的變量。我試圖對此非常小心。 – 2012-07-12 00:29:57

+0

我會這樣說,我只是注意到,我遇到過這個問題的每一個項目都與3D圖形有關。我有一個約400行的頭文件,我寫的是處理向量和矩陣。所以我使用了很多3或16雙打的數組。但是,我非常小心地將它們初始化爲數組或指針,然後分配我需要的內存。在給出可以看到的值之前,不使用矩陣或向量。 – 2012-07-12 00:38:34