33

I keep getting the error "Conversion from string literal to char* is deprecated" in my code. The purpose of the code is to use a pointer-to-pointer to assign string1 and string2 a word, then print it out. How can I fix this?

Here is my code:

#include <iostream>
using namespace std;

struct WORDBLOCK
{
    char* string1;
    char* string2;
};

void f3()
{
    WORDBLOCK word;

    word.string1 = "Test1";
    word.string2 = "Test2";


    char *test1 = word.string1;
    char *test2 = word.string2;

    char** teststrings;

    teststrings = &test1;
    *teststrings = test2;

    cout << "The first string is: "
         << teststrings
         << " and your second string is: "
         << *teststrings
         << endl;  
}
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Andrew T
  • 783
  • 4
  • 11
  • 20
  • 1
    Marking as duplicate for future searches [Deprecated conversion from string literal to 'char\*'](http://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char) – Ricardo Saporta Jul 21 '13 at 22:27

2 Answers2

55

C++ string literals are arrays of const char, which means you can't legally modify them.

If you want to safely assign a string literal to a pointer (which involves an implicit array-to-pointer conversion), you need to declare the target pointer as const char*, not just as char*.

Here's a version of your code that compiles without warnings:

#include <iostream>

using namespace std;

struct WORDBLOCK
{
    const char* string1;
    const char* string2;
};

void f3()
{
    WORDBLOCK word;

    word.string1 = "Test1";
    word.string2 = "Test2";

    const char *test1 = word.string1;
    const char *test2 = word.string2;

    const char** teststrings;

    teststrings = &test1;
    *teststrings = test2;

    cout << "The first string is: "
         << teststrings
         << " and your second string is: "
         << *teststrings
         << endl;
}

Consider what could happen if the language didn't impose this restriction:

#include <iostream>
int main() {
    char *ptr = "some literal";  // This is invalid
    *ptr = 'S';
    std::cout << ptr << "\n";
}

A (non-const) char* lets you modify the data that the pointer points to. If you could assign a string literal (implicitly converted to a pointer to the first character of the string) to a plain char*, you'd be able to use that pointer to modify the string literal with no warnings from the compiler. The invalid code above, if it worked, would print

Some literal

-- and it might actually do so on some systems. On my system, though, it dies with a segmentation fault because it attempts to write to read-only memory (not physical ROM, but memory that's been marked as read-only by the operating system).

(An aside: C's rules for string literals are different from C++'s rules. In C, a string literal is an array of char, not an array of const char -- but attempting to modify it has undefined behavior. This means that in C you can legally write char *s = "hello"; s[0] = 'H';, and the compiler won't necessarily complain -- but the program is likely to die with a segmentation fault when you run it. This was done to maintain backward compatibility with C code written before the const keyword was introduced. C++ had const from the very beginning, so this particular compromise wasn't necessary.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 1
    That was unbelievable clear, resourceful, and enlightening. Thank you for your help, I understand it much better now! – Andrew T Dec 03 '12 at 22:59
  • The explanation is great but the code is unclear and confusing - it looks like you are expecting to print "Test1" and "Test2" while you are actually printing the value of teststrings (an offset pointing to `test1`) and the string pointed to by `test1` (which is "Test2" because you modified `test1` through teststrings) – neuviemeporte Dec 22 '14 at 10:22
  • 1
    @neuviemeporte: (I know I'm a bit late replying.) All I did was add needed `const` keywords to the OP's code. I didn't try to make any other corrections or improvements. – Keith Thompson Sep 17 '15 at 21:32
  • Don't you mean "not an array of const char -- "? – Scooter Mar 03 '17 at 17:27
  • @Scooter: Yes. It took you 4+ years to tell me that? 8-)} Seriously, thanks (I fixed it). – Keith Thompson Mar 03 '17 at 20:01
  • 1
    Even though string literals were `const` in C++ from the beginning, C++03 and earlier seem to have [allowed](https://en.cppreference.com/w/cpp/language/string_literal) an implicit conversion to `char *`. – HolyBlackCat Feb 24 '19 at 22:06
-1

Basically String literals are created in read-only memory. If you attempt to modify the values, segmentation faults at run time in C.

To Overcome this problem in runtime, In C++ Come up Checking at compile time in conversion.

char * n = "String";

In C++, The implicit conversion of String literals to char* not possible, because it is invalid in c++. If you are trying to convert, it will give compilation error.

If you want to use

const char* n = "String";

laddu
  • 11
  • 1
  • 3