I came across a subtle bug a couple of days ago where the code looked something like this:
ostringstream ss;
int anInt( 7 );
ss << anInt << "HABITS";
ss << ends;
string theWholeLot = ss.str();
The problem was that the ends
was sticking a '\0' into the ostringstream
so theWholeLot
actually looked like "7HABITS\0"
(i.e. a null at the end)
Now this hadn't shown up because theWholeLot
was then being used to take the const char *
portion using string::c_str()
That meant that the null was masked as it became just a delimiter. However, when this changed to use strings throughout, the null suddenly meant something and comparisons such as:
if ( theWholeLot == "7HABITS" )
would fail. This got me thinking: Presumably the reason for ends
is a throwback to the days of ostrstream
when the stream was not normally terminated with a null and had to be so that str()
(which then cast out not a string
but a char *
) would work correctly.
However, now that it's not possible to cast out a char *
from a ostringstream
, using ends
is not only superfluous, but potentially dangerous and I'm considering removing them all from my clients code.
Can anyone see an obvious reason to use ends
in a std::string
only environment?
You've essentially answered your own question is as much detail that's needed. I certainly can't think of any reason to use std::ends
when std::string
and std::stringstream
handle all that for you.
So, to answer your question explicitly, no, there is no reason to use std::ends
in a std::string
only environment.
There are some APIs that expect a "string array" with multiple zero terminated strings, a double zero to mark the end. Raymond Chang just recently blogged about it, most of all to demonstrate how often that this gets fumbled.
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