Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it valid to pass nullptr to std::string::assign?

Tags:

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.

like image 567
Bulletmagnet Avatar asked Jan 20 '16 13:01

Bulletmagnet


People also ask

Can std::string be nullptr?

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.

Can you cast a nullptr?

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.

How do you pass an empty string in C++?

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.

Should I use null or nullptr C++?

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 .


1 Answers

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.

like image 166
eerorika Avatar answered Sep 19 '22 13:09

eerorika