Bul*_*net 21 c++ c++-standard-library language-lawyer
我有一个返回指针和长度的函数,我想调用std::string::assign(pointer, length).clear当长度为零且指针可能为nullptr时,是否必须进行特殊情况(调用)?
C++标准说:
21.4.6.3 basic_string::assign
basic_string& assign(const charT* s, size_type n);
Requires: s points to an array of at least n elements of charT.
Run Code Online (Sandbox Code Playgroud)
那么如果n是零呢?什么是零字符数组,如何指向它?打电话有效吗?
s.assign(nullptr, 0);
Run Code Online (Sandbox Code Playgroud)
还是未定义的行为?
s当大小n为零时,libstdc ++的实现似乎不会取消引用指针,但这几乎不是保证.
eer*_*ika 19
小心翼翼地,a nullptr不符合指向大小数组的要求>=0,因此标准不保证行为(它是UB).
另一方面,如果n为零,则不允许实现取消引用指针,因为指针可能是大小为零的数组,并且解引用这样的指针将具有未定义的行为.此外,没有必要这样做,因为没有任何东西被复制.
上述推理并不意味着可以忽略UB.但是,如果没有理由不允许,s.assign(nullptr, 0)那么最好将标准的措辞改为"如果n大于零,那么s指向......".我不知道有什么理由不允许它,但我也不能保证不存在好理由.
请注意,添加支票并不复杂:
s.assign(ptr ? ptr : "", n);
Run Code Online (Sandbox Code Playgroud)
什么是零字符数组
这是:new char[0].自动或静态存储阵列的大小可能不为零.
Nic*_*las 12
好吧,你指出,标准说" s指向阵列......".空指针不指向任意数量元素的数组.甚至不是0个元素.另外,请注意s指向" 至少 n元素的数组......".所以很明显,如果n为零,您仍然可以将合法指针传递给数组.
总体而言,std::stringAPI的空指针没有得到很好的保护charT.所以你应该总是确保你交给它的指针是非空的.
我不确定为什么实现会取消引用任何指向长度为零的数组的指针.
也就是说,我会谨慎行事.你可能会说你不符合标准要求:
21.4.6.3 basic_string :: assign
8要求:s指向至少n个charT元素的数组
因为nullptr没有指向一个数组.
从技术上讲,行为是不确定的.
从标准(2.14.7)[lex.nullptr]:
指针文字是关键字nullptr.它是一种类型的prvalue
std::nullptr_t.[ 注意:std::nullptr_t是一个不同的类型,既不是指针类型也不是指向成员类型的指针 ...]
std::nullptr_t可以根据4.10.1 [conv.ptr]隐式转换为任何类型的空指针.无论空指针的类型如何,事实仍然是它指向任何东西.
因此,它不满足s指向charT的至少n个元素的数组的要求.
这似乎是未定义的行为.
有趣的是,根据这个答案,C++ 11标准明确指出,它s必须不是basic_string构造函数中的空指针,但此后的措辞已被删除.