【问题标题】:Avoid or warn on implicit conversion from const char* to bool in GCC在 GCC 中避免或警告从 const char* 到 bool 的隐式转换
【发布时间】:2019-06-28 04:09:07
【问题描述】:

考虑以下代码:

void foo(bool parameter) {
    std::cout << parameter << "\n";
}

int main() {
    foo("const char *argument");
}

我希望编译器在将 const char* 而不是 bool 作为参数传递给函数 foo 时发出警告。

但 GCC 会隐式转换它。我试过-Wall-Wextra-Wpedantic,但这些都没有发出警告。有没有可以捕捉到这种隐式转换(无效参数类型)的标志?

忽略函数具有bool 类型的参数这一事实,有些人可能认为这是不好的代码风格。我无法重构那部分。

标准刚刚提到会出现这样的implicit conversion

整数、浮点、无范围枚举、指针和指向成员的指针类型的纯右值可以转换为布尔类型的纯右值。

我知道这种行为在if (ptr) 语句中很方便,但对我来说,在传递参数的情况下,这显然是错误的,并且是错误的来源。

【问题讨论】:

  • ...也有利于意外:如果有一个函数接受std::string 而另一个接受bool,请猜猜为"const char *argument" 选择了哪个函数。 (剧透警报:是的,第二个 - 它让我发疯,直到我得到一个线索。);-)
  • 有点离题,但我很困惑为什么你认为有一个bool 参数会是不好的编码风格..
  • @user463035818 “鲍勃叔叔这么说”可能是一个很好的理由。他认为带有bool 参数的函数从来没有单一的职责。不过,鲍勃叔叔对编码有很多强烈的看法。
  • @Yksisarvinen 你的意思是应该有一个fooTrue 和一个fooFalse 代替?嗯,也许在某些情况下我可以同意,但一般情况下不同意,尽管如果 Bob 这么说,那肯定有一些道理
  • 隐式转换是 C++ 语言中最大的错误之一。隐式整数转换可能是指针之外最大的一般错误来源之一。这是一个很好的问题,感谢您思考如何设计界面以防止代码中的错误。

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


【解决方案1】:

您可以将指针的 foo 重载声明为 deleted

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

或者更好的是,作为@Ted cmets,只需声明一个香草重载即可不编译任何隐式转换:

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

【讨论】:

  • 没错,但在现实世界的例子中,这些可能是(多个)函数(甚至可能来自其他文件/来源),这可能会让这看起来很累。
  • 从 C++11 开始,你应该将其声明为 deleted... 这将生成更早且更有意义的错误消息。或者,如果T 不是bool,则使用引发static_assert 的主体声明它(如果模板总是引发static_assert,则模板格式错误,这是进行此检查的唯一原因)。
  • ... 或只是 void foo(T) = delete; 删除所有隐式转换。
【解决方案2】:

我希望编译器在将 const char* 而不是 bool 作为参数传递给函数 foo 时发出警告。 ...我试过-Wall-Wextra-Wpedantic

您需要将-Wconversion 添加到您的编译器标志中。请注意,这似乎适用于clang(最新或旧版本),但不适用于gcc

如果这触发了太多您不想处理的警告,您可以选择性地启用-Wstring-conversion(仅限clang)。

【讨论】:

猜你喜欢
  • 2011-10-24
  • 2020-12-30
  • 1970-01-01
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多