Reputation: 3774
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
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
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
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