Pergunta

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?!

Foi útil?

Solução

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 to wchar_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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top