2013-01-16 26 views
2

升級一些遺留代碼,我開始獲得「警告:將NULL傳遞給'Identifier :: Identifier(int)'的非指針參數1 [-Wconversion-null ]「來自g ++的消息。大多數情況下這很好,但似乎沒有考慮到具有多個構造函數的類。-Wconversion-null不考慮所有構造函數

例如,藉此測試代碼:

#include <stdio.h> 

class Identifier 
{ 
    private: 
    int m_iID; 

    public: 
    Identifier(const char* p_c) { m_iID = p_c ? p_c[0] : 0; } 
    Identifier(int i) { m_iID = i; } 
}; 

int main(int argc, char* argv[]) 
{ 
    Identifier* p_ID = new Identifier(NULL); 

    return 0; 
} 

(請忽略什麼構造函數實際上做,這只是問題的說明對於背景下,有問題的代碼是存儲的一類。標識符以散列值的形式存在,構造函數可以將字符串轉換爲散列值,或直接轉換爲散列值)。

第三行到最後一行的「new」語句會引發此警告。令我困惑的是g ++顯然假設它需要使用Identifier(int i)構造函數,並且忽略標識符(const char * p_c)構造函數,其中的一個指針。

請注意,將ints更改爲unsigned ints會導致歧義錯誤,而這是32位系統。

我知道指定-Wno-conversion-null會解決問題,就像傳遞0或明確地將NULL轉換爲const char *一樣。但我很好奇爲什麼看似有效的構造函數被忽略。另外,我希望避免大規模的搜索和替換工作,同時保持警告有效。

回答

2

至少在此CentOS的框,NULL在linux/stddef.h定義:

#undef NULL 
#if defined(__cplusplus) 
#define NULL 0 
#else 
#define NULL ((void *)0) 
#endif 

這樣,在C++ NULL是的整數;因此編譯器默認選擇構造函數爲int,併爲您提供警告。

+0

但它也是一個有效的事情來設置一個指針(這是__null在我的Xubuntu框這裏)。 – subi211

+1

這是真的,Subi211,它是*爲什麼*編譯器警告你。你在你的代碼中使用了'NULL',這表明你打算使用一個指針相關的函數,但是C++的規則說'int'構造函數是編譯器需要選擇的。這可能不是你想要的,所以編譯器會警告你。 'NULL'可分配給指針,但首先是'int'。 –

+0

@ subi211如果C++ 11對您可用,您可以使用nullptr而不是NULL。 –