【问题标题】:enforcing type safety when casting char* to bool in C++11在 C++11 中将 char* 强制转换为 bool 时强制类型安全
【发布时间】:2015-12-19 07:32:52
【问题描述】:

以下代码编译良好,没有任何警告(默认选项为 g++)。在这种情况下,我们可以使用一个标志来要求 g++ 发出警告吗?

void foo(bool v) {
}

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

【问题讨论】:

  • 如果 将原始字符串文字作为参数 是唯一可以添加 void foo(const char*) = delete; 重载的问题
  • @PaoloM "警告:命令行选项 '-Wimplicit' 对 C/ObjC 有效,但对 C++ 无效"
  • @JoachimPileborg 实际上,g++(4.9.33,cygwin)似乎在重载之前考虑了已删除的foo(const void *)。我必须查一下才能确定,但​​我想这是重载解决的顺序,并且删除的函数参与其中。
  • 反过来template<typename T> void foo(T) = delete; 会捕获任何不是bool cv {,&,&&} 的东西。
  • @davmac 尽管名字很可爱,-Wall 并不能打开一切。例如。有-Wextra,还有更多。

标签: c++ c++11 gcc implicit-conversion gcc-warning


【解决方案1】:

我喜欢尝试clang -Weverything 并选择弹出的警告:

void foo(bool) {}

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

void baz() {
    foo(nullptr);    
}

int main() {}

main.cpp:5:7: 警告:隐式转换将字符串文字转换为 bool: 'const char [5]' to 'bool' [-Wstring-conversion] foo("test");

main.cpp:8:9: 警告:nullptr 常量隐式转换为 'bool' [-Wnull 转换] foo(nullptr);

不幸的是,g++ 不支持-Wstring-conversion-Wnull-conversion。您可以尝试向 gcc 提交功能请求/错误报告。

【讨论】:

  • “在这种情况下,我们可以使用一个标志要求 g++ 发出警告吗?”
  • @PiotrSkotnicki 我用 -Weverything 来查找会触发哪个警告,可惜g++不支持这个
【解决方案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&lt;char const&gt;(char const*) 引起的。错误的准确措辞取决于链接器。

请注意,开发人员可以故意规避这些错误。但是这样的技术会阻止意外使用。

如果您想允许传递除 char const * 之外的任何指针,只需像上面一样声明 void foo(const char *) 并且不要声明模板。

【讨论】:

  • =delete 更好,给出编译器而不是链接器错误
  • =delete 是否可以使用模板?只是问问。
  • 更好的取决于视角。不是每个人都可以更新到 C++11。无论如何,我会更新以引用 C++11。
  • @Peter OP 将其标记为 C++11,所以这是公平的游戏。对于那些不能使用它的不幸的人:打电话给你的猎头 :)
  • OP 将其标记为 C++ 以及 C++11。有充分的理由坚持使用旧版本.....这不仅仅是发布更新命令那么简单。
猜你喜欢
  • 1970-01-01
  • 2014-02-04
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多