2014-08-28 32 views
3

假設我們有一個聲明爲以下功能:隱式轉換傳遞參數時,函數C語言

void myFunct(unsigned char a); 

在我的主程序我把它叫做這樣myFunct(5000),我得到這樣的警告: 「整數轉換導致截斷「。 編譯器警告我說,我經過大於255

值無論如何,如果一個聲明一個變量const ulong test = 5000,我把它傳遞給myFunct myFunct(test),編譯器不提醒我差不多的可能問題。

任何人都可以解釋我這種行爲嗎?

這個缺失的警告在我的代碼中引起了一個惱人的錯誤,我現在害怕這些問題可能出現在其他地方。

我試過不同的編譯器,如MinGW和GHS版本5(GreenHills),都沒有警告我關於報告的問題。

任何人都可以告訴我,如果有辦法來防止這種問題?

+1

嘗試靜態C/C++代碼分析工具:cppcheck,viva64等 – Ilya 2014-08-28 09:09:00

回答

4

編譯器警告不需要任何邏輯。編譯器會嘗試提出有關您可能想知道的問題的有用警告,並避免浪費您的時間和誤報。任何滿足這兩個衝突目標的啓發式算法都可以在編譯器中實現。

這裏最有可能的解釋是,在myFunct(5000),很明顯的是,轉換無法保存的價值,而在myFunct(test),這不是明擺着只在函數調用期待。關於後者的警告需要知道test的值,並且編譯器可能沒有機制來確定test在那一點的值爲5000

儘管在這個特例中test的值總是5000,但預測變量值的機制在所有情況下都不能很好地工作(非常量變量的值是難以預測)可能阻礙編譯器編寫者甚至試圖實施這樣的警告。

靜態分析儀解決了與編譯器不同的目標。至少在簡單情況下,他們試圖預測變量的值,其中一些可能是可配置的,以便在您的示例中警告myFunct(test)。大多數靜態分析儀仍然保留不警告,如果他們不確定是否存在問題,並且您永遠不知道他們將確定或不確定。但是,使用靜態分析器獲得警告的機會比使用編譯器的機會要好。

注意,會發生什麼的myFunctmyFunct(5000)參數是轉換。 A 轉換是一個句法結構。沒有像「隱式演員」這樣的事情。

+0

我明白你的解釋,我認爲它是有效的。無論如何,正在考慮這種情況: 假設有一個char mychar = mylong(其中mylong是5000)。在這種情況下,編譯器會警告我。我期望在我上面報告的函數調用的情況下具有相同的行爲。我錯了嗎?感謝您的回覆和您的建議。 – 2014-08-28 10:09:22

+0

@SimoneBonetti你讓我想起了一個我打算包含在我的答案中的句子,但忘記了:不能解決變量的實際值,只知道'test'的類型(這是需要計算的靜態信息無論如何,所以它是可用的),編譯器通常會避免警告'myFunct(test)',因爲'test'可能是一個'ulong'變量,其中包含一個可表示爲'unsigned char'的值。 – 2014-08-28 10:57:18