2015-09-22 80 views
6

以下代碼在沒有任何警告的情況下編譯正確(默認選項爲g ++)。在這種情況下,是否有我們可以用來要求g ++發出警告的標誌?在C++中強制類型安全時將char *轉換爲bool 11

void foo(bool v) { 
} 

void bar() { 
    foo("test"); 
} 
+1

嘗試'-Wimplicit' –

+0

這不僅是字符文字和指向受此影響的字符的指針,而是所有*指針都可以隱式轉換爲'bool'。 –

+3

if *作爲參數的原始字符串文字*是唯一可以添加'void foo(const char *)= delete;'overload –

回答

3

我喜歡嘗試clang -Weverything並挑選跳出警告:

void foo(bool) {} 

void bar() { 
    foo("test"); 
} 

void baz() { 
    foo(nullptr);  
} 

int main() {} 

main.cpp中:5:7:警告:隱式轉換變成字符串文字到 布爾:「常量char [5]'到'bool'[-Wstring-conversion] foo(「test」);

main.cpp:8:9:warning:隱式轉換nullptr常量爲 'bool'[-Wullull-conversion] foo(nullptr);

不幸的是,g ++不支持-Wstring-conversion-Wnull-conversion。您可以嘗試向gcc提交功能請求/錯誤報告。

+2

*「在這種情況下,我們可以使用**來請求g ++ **發出警告嗎?」* –

+0

@PiotrSkotnicki現在,您比g ++更''pedantic'! ... –

+2

@PiotrSkotnicki我用 - 萬物找到哪個警告將被觸發,不幸的是,這個不被g ++支持 – TemplateRex

2

如果我真的想阻止這樣的函數傳遞一個指針,我會在C++ 11中做到這一點;

void foo(bool); 
template<class T> void foo(T *) = delete; 

void bar() 
{ 
    foo("Hello"); 
} 

這將觸發編譯器錯誤。

在C++ 11之前(不是每個人都可以因各種原因更新)一種技術是;

void foo(bool); 
template<class T> void foo(T *); // note no definition 

void bar() 
{ 
    foo("Hello"); 
} 

,然後有(你的構建內有且僅有一個編譯單元)中的foo(bool)某處定義。對於大多數使用傳統編譯器和鏈接器的工具鏈(實際上這是大多數工具鏈,包括大多數g ++的安裝),鏈接器錯誤是由foo<char const>(char const*)未定義引起的。錯誤的準確措辭是鏈接器的依賴。

請注意,錯誤可以由開發人員有意規避。但是這樣的技術將會阻止意外使用。

如果你想允許傳遞除外char const *任何指針,只需如上聲明void foo(const char *)和不申報的模板。

+3

'= delete'更好,給編譯器而不是鏈接器錯誤 – TemplateRex

+0

'= delete'是否可以使用模板?只是問問。 –

+0

更好取決於視角。不是每個人都可以更新到C++ 11。無論如何,我會更新到參考C++ 11。 – Peter

相關問題