调试断言失败(无效空指针)默认字符串参数

Debug Assertion Failed (invalid null pointer) default string parameter

本文关键字:默认 字符串 参数 空指针 无效 断言 失败 调试      更新时间:2023-10-16

以下代码

void f(const std::string &s = {}) {
}
f();

在Visual Studio 2013中生成Debug Assertion Failed (invalid null pointer)(调试版本)。它在gcc中运行正常(我可以将s.length()设置为0)。当试图构建s时,它看起来像一个错误:

下面是调用栈:

坐标系:

f(); <-- HERE --

框架(xstring):

basic_string(const _Elem *_Ptr)
  : _Mybase()
  { // construct from [_Ptr, <null>)
  _Tidy();
  assign(_Ptr); // <-- HERE --
  }

框架(xstring):

_Myt& assign(const _Elem *_Ptr)
  { // assign [_Ptr, <null>)
  _DEBUG_POINTER(_Ptr); <-- HERE --
  return (assign(_Ptr, _Traits::length(_Ptr)));
  }

框架(xutility):

template<class _Ty> inline
  void _Debug_pointer(const _Ty *_First, _Dbfile_t _File, _Dbline_t _Line)
  { // test iterator for non-singularity, const pointers
  if (_First == 0)
    _DEBUG_ERROR2("invalid null pointer", _File, _Line); <-- HERE --
  }

看起来是用(const char *)调用构造函数而不是默认构造函数。

当我尝试这个时:

std::string x = {}; // local variable

调用默认构造函数

这是Visual Studio上的一个bug还是我错过了什么?

我知道一个解决办法是void f(const std::string &s = ""),但我想使用默认初始化器,这是一个非常奇怪的行为。

这是一个bug。

如果它不是一个bug,那么你应该得到模棱两可的构造函数错误,因为被调用的构造函数不是默认构造函数,而默认构造函数可以被调用。

下面的代码可以在Visual c++ 12.0 (Visual Studio 2013附带的编译器)下编译:

struct X
{
    X( char const* ) {}
};
void g( X const& = {} ) {}

不能编译

以下代码,其中构造函数参数不是默认可构造的,编译失败:

struct Y
{
    struct E { E( int ){} };
    Y( E ) {}
};
void h( Y const& = {} ) {}

具有枚举类型构造函数实参的中间情况可以编译,因此显然初始化式{}不会转换为{0},而是转换为{{}} –如果我可以推测,也许是为了抑制std::array初始化的警告?


我已经向微软提交了一个bug报告。