I have a function which returns a pointer and a length, and I want to call std::string::assign(pointer, length)
. Do I have to make a special case (calling clear
) when length is zero and the pointer may be nullptr?
The C++ standard says:
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.
So what if n
is zero? What is an array of zero characters and how does one point to it? Is it valid to call
s.assign(nullptr, 0);
or is it undefined behavior?
The implementation of libstdc++ appears not to dereference the pointer s
when the size n
is zero, but that's hardly a guarantee.
Since C++23 adopted P2166, it is now forbidden to construct std::string from nullptr , that is, std::string s = nullptr or std::string s = 0 will no longer be well-formed.
For the first function, yes, you can cast the returned std::nullptr_t to another pointer type (you don't even need a cast to do the conversion, it will happen implicitly) but that's probably not something you ever want to do.
std::string::clear in C++ The string content is set to an empty string, erasing any previous content and thus leaving its size at 0 characters.
As I mentioned above, the general rule of thumb that I recommend is that you should start using nullptr whenever you would have used NULL in the past. As a reminder, since C++11, NULL can be either an integer literal with value zero, or a prvalue of type std::nullptr_t .
Pedantically, a nullptr
does not meet the requirements of pointing to an array of size >=0
, and therefore the standard does not guarantee the behaviour (it's UB).
On the other hand, the implementation wouldn't be allowed to dereference the pointer if n
is zero, because the pointer could be to an array of size zero, and dereferencing such a pointer would have undefined behaviour. Besides, there wouldn't be any need to do so, because nothing is copied.
The above reasoning does not mean that it is OK to ignore the UB. But, if there is no reason to disallow s.assign(nullptr, 0)
then it could be preferable to change the wording of the standard to "If n is greater than zero, then s points to ...". I don't know of any good reason to disallow it, but neither can I promise that a good reason doesn't exist.
Note that adding a check is hardly complicated:
s.assign(ptr ? ptr : "", n);
What is an array of zero characters
This is: new char[0]
. Arrays of automatic or static storage may not have a zero size.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With