Calling std::string::assign(const CharT* s, size_type count) with count 0 safe?

Viewed 62

Is the following code safe?

#include <string>
#include <cassert>

int main() {
    std::string s = "ABC";

    // https://en.cppreference.com/w/cpp/string/basic_string/assign
    s.assign(nullptr, 0);
    
    assert(s.empty());
}

Demo: https://wandbox.org/permlink/SYTJlzc4DkzaUekv


Added this part in order to clarify my question point.

I expect that passing not only nullptr but also uninitialized pointer is safe as follows if size (length) parameter n is 0.

#include <string>
#include <cassert>

int main() {
    std::string s = "ABC";

    // https://en.cppreference.com/w/cpp/string/basic_string/assign
    char* uninitialized;
    s.assign(uninitialized, 0);
    
    assert(s.empty());
}

Demo: https://wandbox.org/permlink/UeSX0NWRPaS6OvqT


The actual code is a part of generic function.

I don't want to check the second argument size is 0 or not. But I'm not sure it is safe.


Added to describe why I don't want to check the second argument.

Here is a PoC code. I want to write the function as func2(). If the std::string::assign() call is safe, func1() is redundant for me.

#include <string>
#include <cassert>

void func1(std::string& target, char* s, std::size_t n) {
    if (n == 0) target.clear();
    else target.assign(s, n);
}

void func2(std::string& target, char* s, std::size_t n) {
    target.assign(s, n);
}

int main() {
    char* uninitialized;
    std::size_t n = 0;
    {
        std::string s = "ABC";
        func1(s, uninitialized, n);
        assert(s.empty());
    }
    {
        std::string s = "ABC";
        func2(s, uninitialized, n);
        assert(s.empty());
    }
}

Demo: https://wandbox.org/permlink/PK8vIvw4XKrICsqe


According to https://timsong-cpp.github.io/cppwp/n4659/string.assign

basic_string& assign(const charT* s, size_type n);

Requires: s points to an array of at least n elements of charT.

Throws: length_­error if n > max_­size().

Effects: Replaces the string controlled by *this with a string of length n whose elements are a copy of those pointed to by s.

If n is 0 then s must contains at least 0 elements. So requirements are satisfied. Replaces the string controlled by *this with a string of length 0. So the string controlled by *this is replaced with the empty string.

Am I understanding correctly?

0 Answers
Related