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?