【问题标题】:Why does constructing std::string(0) not emit a compiler warning?为什么构造 std::string(0) 不会发出编译器警告?
【发布时间】:2012-11-15 09:02:06
【问题描述】:

假设我有这段代码。

#include <string>

int main()
{
    std::string(0);
    return 0;
}

编写std::string(0) 会导致调用std::basic_string&lt;char&gt;::basic_string(const char*),并将0 作为此构造函数的参数,该构造函数尝试将参数视为指向C 字符串的指针。

运行此代码显然会导致std::logic_error 被抛出。但我的问题是:为什么 GCC 和 MSVC 8.0 都不发出任何警告?我希望看到类似于“从不进行强制转换的整数制作指针”的内容。

【问题讨论】:

  • 因为0 是一个空指针常量,而且大概没有人认为警告值得付出努力(真的,有人多久会写一次这样的东西?)
  • 演员阵容有什么帮助?这同样是荒谬的
  • 我想我在 C 年一定已经习惯了这个警告。用gcc 编译int *x = 5 会导致发出“初始化使指针从整数不进行强制转换”。
  • 因为用空指针初始化指针是非常非常常见的,绝不会出错。添加警告会导致每个程序发出大量警告。
  • “运行此代码显然会导致 std::logic_error 被抛出”——顺便说一句,这不能保证,您的代码具有未定义的行为。

标签: c++ compiler-construction stl compiler-warnings


【解决方案1】:

0是一个值为0的整型常量表达式,所以它是一个空指针常量。使用 0 值常量作为空指针不是强制转换。

C++11 引入了nullptr(和nullptr_t),但将0 视为空指针的处理方式在不久的将来不太可能改变,因为大量代码依赖于它。

【讨论】:

    【解决方案2】:

    因为那些编译器似乎错过了这个功能。我建议给他们写一份功能报告。

    编译器可以轻松地在内部重新识别标准字符串类并发出合理的警告。

    我不知道您为什么要将警告仅限制在无演员表的情况下。在那里进行强制转换或以其他方式传递空指针同样不明智。

    【讨论】:

    • 我不认为提问者真的想将其限制在无演员表的情况下,只是他引用了他在其他情况下经常看到的错误(你已经解释过的不是无论如何在这里相关)。非强制转换的情况可能是最有可能的,因为我希望任何编写std::string(0) 的人都试图调用一个具有一定大小的虚构构造函数(如vector 具有),并且实际上意味着string(0,0)。写string((char*)0) 的人并没有犯那个错误,他们自己想出了另一个不太可能的错误。
    猜你喜欢
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多