[c++] C++ deprecated conversion from string constant to 'char*'

I have a class with a private char str[256];

and for it I have an explicit constructor:

explicit myClass(const char *func)
{
    strcpy(str,func);
}

I call it as:

myClass obj("example");

When I compile this I get the following warning:

deprecated conversion from string constant to 'char*'

Why is this happening?

This question is related to c++ string explicit-constructor

The answer is


The following illustrates the solution, assign your string to a variable pointer to a constant array of char (a string is a constant pointer to a constant array of char - plus length info):

#include <iostream>

void Swap(const char * & left, const char * & right) {
    const char *const temp = left;
    left = right;
    right = temp;
}

int main() {
    const char * x = "Hello"; // These works because you are making a variable
    const char * y = "World"; // pointer to a constant string
    std::cout << "x = " << x << ", y = " << y << '\n';
    Swap(x, y);
    std::cout << "x = " << x << ", y = " << y << '\n';
}

Maybe you can try this:

void foo(const char* str) 
{
    // Do something
}

foo("Hello")

It works for me


As answer no. 2 by fnieto - Fernando Nieto clearly and correctly describes that this warning is given because somewhere in your code you are doing (not in the code you posted) something like:

void foo(char* str);
foo("hello");

However, if you want to keep your code warning-free as well then just make respective change in your code:

void foo(char* str);
foo((char *)"hello");

That is, simply cast the string constant to (char *).


A reason for this problem (which is even harder to detect than the issue with char* str = "some string" - which others have explained) is when you are using constexpr.

constexpr char* str = "some string";

It seems that it would behave similar to const char* str, and so would not cause a warning, as it occurs before char*, but it instead behaves as char* const str.

Details

Constant pointer, and pointer to a constant. The difference between const char* str, and char* const str can be explained as follows.

  1. const char* str : Declare str to be a pointer to a const char. This means that the data to which this pointer is pointing to it constant. The pointer can be modified, but any attempt to modify the data would throw a compilation error.
    1. str++ ; : VALID. We are modifying the pointer, and not the data being pointed to.
    2. *str = 'a'; : INVALID. We are trying to modify the data being pointed to.
  2. char* const str : Declare str to be a const pointer to char. This means that point is now constant, but the data being pointed too is not. The pointer cannot be modified but we can modify the data using the pointer.
    1. str++ ; : INVALID. We are trying to modify the pointer variable, which is a constant.
    2. *str = 'a'; : VALID. We are trying to modify the data being pointed to. In our case this will not cause a compilation error, but will cause a runtime error, as the string will most probably will go into a read only section of the compiled binary. This statement would make sense if we had dynamically allocated memory, eg. char* const str = new char[5];.
  3. const char* const str : Declare str to be a const pointer to a const char. In this case we can neither modify the pointer, nor the data being pointed to.
    1. str++ ; : INVALID. We are trying to modify the pointer variable, which is a constant.
    2. *str = 'a'; : INVALID. We are trying to modify the data pointed by this pointer, which is also constant.

In my case the issue was that I was expecting constexpr char* str to behave as const char* str, and not char* const str, since visually it seems closer to the former.

Also, the warning generated for constexpr char* str = "some string" is slightly different from char* str = "some string".

  1. Compiler warning for constexpr char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *const'
  2. Compiler warning for char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *'.

Tip

You can use C gibberish ? English converter to convert C declarations to easily understandable English statements, and vice versa. This is a C only tool, and thus wont support things (like constexpr) which are exclusive to C++.


I also got the same problem. And what I simple did is just adding const char* instead of char*. And the problem solved. As others have mentioned above it is a compatible error. C treats strings as char arrays while C++ treat them as const char arrays.


I solve this problem by adding this macro in the beginning of the code, somewhere. Or add it in <iostream>, hehe.

 #define C_TEXT( text ) ((char*)std::string( text ).c_str())

For what its worth, I find this simple wrapper class to be helpful for converting C++ strings to char *:

class StringWrapper {
    std::vector<char> vec;
public:
    StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
    }

    char *getChars() {
        return &vec[0];
    }
};

There are 3 solutions:

Solution 1:

const char *x = "foo bar";

Solution 2:

char *x = (char *)"foo bar";

Solution 3:

char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");

Arrays also can be used instead of pointers because an array is already a constant pointer.


In fact a string constant literal is neither a const char * nor a char* but a char[]. Its quite strange but written down in the c++ specifications; If you modify it the behavior is undefined because the compiler may store it in the code segment.


The warning:

deprecated conversion from string constant to 'char*'

is given because you are doing somewhere (not in the code you posted) something like:

void foo(char* str);
foo("hello");

The problem is that you are trying to convert a string literal (with type const char[]) to char*.

You can convert a const char[] to const char* because the array decays to the pointer, but what you are doing is making a mutable a constant.

This conversion is probably allowed for C compatibility and just gives you the warning mentioned.