今天把項目的Qt版本從Qt4.6.3升級到Qt4.8.4,重新編譯項目代碼的時候,特別關注了一下編譯器的警告。於是找到《C++編程規範——101條規則、準則與最佳實務》翻了翻,重溫了一下第1條 在進階別警告乾淨利落地進行編譯。
如果編譯器對某個構造發出警告,一般表明代碼中存有潛在的問題。警告就好比代碼的“腫瘤”,可能是良性的也可能是惡性的——作為代碼醫生的我們不能對其視而不見。必須“把它弄清楚”,然後通過“改寫代碼以排除警告”!
典型的編譯器警告樣本:
1、"Unused function parameter"(未使用的函數參數):
編譯器會對沒有使用到的函數參數報警示告。如果確實不需要,那直接刪除函數參數名就行了。
2、"Variable defined but never used"(定義了從未使用過的變數):
如果確實不需要,可以直接將之刪除。 如果該變數的執行個體化是為了啟動某項服務,則經常可以通過插入一個變數本身的求值運算式,使編譯器不再警示。(這種求值不會影響運行時的速度)
3、"Variable may be used without being initialized"(變數使用前可能未經初始化):
這種警告通常意味著你的代碼存在問題,請謹慎處理之。
4、 "Missing return"(遺漏了return語句)。:
這可能是一種好現象。即使你認為控制永遠都不會運行到結尾或某個分支,則應該加上執行assert(false ) 的語句。
像下面這樣(兼有注釋作用的斷言):
default:
assert( !"should never get here!" ); // !"string" 的求值結果為false
5、"signed/unsigned mismatch"(有符號數/無符號數不匹配):
通常需要插入一個顯式的強制轉換。
6、 "warning: type qualifiers ignored on function return type"(忽略了函數傳回型別的類型限定符):
通常是因為在函數前面的傳回值面前添加了多餘的 const 限定符。
例如,const int getAge() const { return m_age; } ,最前面的const 是多餘的,編譯器會報警示告。
7、 "warning: deprecated conversion from string constant to 'char*'"(不推薦的轉化用法):
函數原型:void setName(char *name);
函數調用:setName("personName"); // 編譯器報警示告
釋義:這是因為 char * 是一個指標,其背後的含義是:給我一個字串,我可以修改它。
而如果我們傳給函數一個“字串常量”,這應該是沒法被修改的。所以說,比較合理的辦法是把參數類型修改為const char * ,而這個類型背後的含義是:給我一個字串,我只要讀取它(const意味著唯讀)。
8、 "warning: "MAX_PATH" redefined" (重複定義) :
#ifndef MAX_PATH
#define MAX_PATH(260)
#endif
9、第三方標頭檔。
10、"auto-importing has been activated without --enable-auto-import specified on the command line"
當然,對純屬雜訊的警告,如果一時無法提供消除的方法。應該單獨禁用這個警告,並且編寫一個清晰的注釋,說明為什麼要禁用。