babon
babon

Reputation: 3774

String initialization and printing

Table 3.1 under article 3.2.1 in C++ Primer, Fifth edition states:

string s3("value") -> s3 is a copy of the string literal, not including the null.

My interpretation of this is - when we initialize a string like string s1("value");, the variable s1 contains a copy of the string value without the NUL character at the end.

#include <iostream>

using std::cin;
using std::string;
using std::cout;
using std::endl;

int main(void)
{
        string s1("value");

        cout << s1 << endl;   // prints - value
}

So, does this program invoke UB as s1 does not have a NUL terminator and we are printing the string?

I am asking this because, in C, trying to print a c-string without a NUL terminator produces UB. Is it not mandatory for strings in C++ to end with a NUL?

What am I missing here?

Upvotes: 1

Views: 126

Answers (3)

NathanOliver
NathanOliver

Reputation: 180500

So, does this program invoke UB as s1 does not have a NUL terminator and we are printing the string?

No. std::string provides an overload of operator << that "does the right thing". You don't have to worry about it.

I am asking this because trying to print a c-string without a NUL terminator produces UB. Is it not mandatory for strings in C++ to end with a NUL?

That will depend on which version of the standard you are using C++98/03 doesn't require there to be a null terminator at the end of the string but c_str basically forces you to do so. C++11 and above though do guarantee that there is a null terminator at the end of the string data.

Do note that the terminating null character is still not needed as std::string's operator << could look like

for (size_t i = 0; i < member_variable_size; ++i)
    std::cout << member_variable_data[i]

so it would work regardless if there was one or not. In fact it pretty much has to do this since std::string is allowed to have embedded nulls in it and it will string print correctly like how

int main() 
{
    std::string foo("h\0ell\0o", 7);
    std::cout << foo;
}

prints

hello

Upvotes: 2

lubgr
lubgr

Reputation: 38267

What am I missing here?

This operator overload that takes a std::string as the second argument. So std::cout << s1 doesn't print a c-string without a null terminator, you are invoking a function operator << and pass s1 to it.

So, does this program invoke UB as s1 does not have a NUL terminator and we are printing the string?

In general, you can rely upon the competence of the developers behind the standard library in use, i.e., it seems safe to me to use this overloaded operator :)

Upvotes: 1

Paul Evans
Paul Evans

Reputation: 27567

Is it not mandatory for strings in C++ to end with a NUL?

Depends on what you mean by "strings". std::string do not end in a nul character because the length is known/stored. C-style strings (aka char* arrays) returned by std::string::c_str() must end a nul character because the length is unknown/not stored.

Upvotes: 3

Related Questions