std::string
provides const char* c_str ( ) const which:
Get C string equivalent
Generates a null-terminated sequence of cha
I see at least two problems with the implicit conversion:
Even the explicit conversion that c_str()
provides is dangerous enough as is. I've seen a lot of cases where the pointer was stored to be used after the lifetime of the original string object had ended (or the object was modified thus invalidating the pointer). With the explicit call to c_str()
you hopefully are aware of these issues. But with the implicit conversion it would be very easy to cause undefined behavior as in:
const char *filename = string("/tmp/") + name;
ofstream tmpfile(filename); // UB
The conversion would also happen in some cases where you wouldn't expect it and the semantics are surprising to say the least:
string name;
if (name) // always true
;
name-2; // pointer arithmetic + UB
These could be avoided by some means but why get into this trouble in the first place?That's probably because this conversion would have surprising and peculiar semantics. Particularly, the fourth paragraph you quote.
Another reason is that there is an implicit conversion const char* -> string
, and this would be just the converse, which would mean strange behavior wrt overload resolution (you shouldn't make both implicit conversions A->B
and B->A
).
Because C-style strings are a source of bugs and many security problems it's way better to make the conversion explicitly.
The Josuttis book says the following:
This is for safety reasons to prevent unintended type conversions that result in strange behavior (type
char *
often has strange behavior) and ambiguities (for example, in an expression that combines astring
and a C-string it would be possible to convertstring
intochar *
and vice versa).
Because implicit conversions almost never behave as you expect. They can give surprising results in overload resolution, so it's usually better to provide an explicit conversion as std::string does.
From the C++ Programming Language 20.3.7 (emphasis mine):
Conversion to a C-style string could have been provided by an operator const char*() rather than c_str(). This would have provided the convenience of an implicit conversion at the cost of surprises in cases in which such a conversion was unexpected.