2015-09-22 44 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

相关问题