So I have this code:
class ConstTest {
public:
explicit ConstTest(char* name) {}
};
int main() {
ConstTest t("blarghgh");
}
It obviously compiles, even though I thought that it shouldn't. As string literals in C++ have type const char[]
, and ConstTest
constructor requires a const-less char*
— not const char*
. And casting a const
pointer to a non-const one isn't something usually done by C++ implicitly.
So, where I'm wrong? Why it's compiling? Can I legally modify the dereferenced pointer inside the constructor?!
So, where I'm wrong? Why it's compiling?
It is compiling because your compiler is too permissive, and your compiler is too permissive because in C++03 the implicit conversion from a string literal to char*
was only deprecated, not invalid.
The rationale was backward compatibility with legacy C APIs. Per paragraph 4.2/2 of the C++03 Standard:
A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type “pointer to
char
”; a wide string literal can be converted to an rvalue of type “pointer towchar_t
”. In either case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue. [Note: this conversion is deprecated. See Annex D.]
In C++11, however, the implicit conversion is illegal (the above paragraph has been removed altogether).
Can I legally dereference-and-modify the pointer inside the constructor?!
You can, but you cannot modify the dereferenced object. Doing so would be undefined behavior, since the type of the object is const
-qualified.
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