Conversion from String Literal to Char* Is Deprecated

Deprecated conversion from string literal to 'char*'

The strings that you enter: "red", "organge" etc are "literal", because they are defined inside the program code itself (they are not read directly from disk, user input /stdin etc.).

This means that if at any point you try to write to your colors you will be directly accessing your original input and thus editing it. This would cause some undesired run-time errors.

Declaring it as a const will make sure that you will never try to write to this pointer and such a run-time error can be avoided.

const char *colors[4] = {"red", "orange", "yellow", "blue"};

If you ever feel like editing these values at runtime, then you should copy the strings first.

deprecated conversion from string to char *

warning: conversion from a string literal to "char *" is deprecated

This almost certainly means that you are using a C++ compiler. String literals (like "default_file.txt" in your example) was once of type char[] in C and C++ both. Writing to a string literal invokes undefined behavior. Because of this, C++ changed the type of string literals to const char[]. But in C, the type remains char[]. The warning is therefore an indication that you are using a C++ compiler for compiling C code, which is often not wise.

Note that it is however bad practice in C as well as C++, to have a non-const-qualified pointer to a string literal.


Now, I get error: expression must be a modifiable lvalue.

Because you can't assign a value to an array in run-time using assignment operators. The C syntax does not allow this. You would have to use memcpy, strcpy or similar.


Corrected code should be something like this:

static const char* fName = "default_file.txt";

if (argc == 2 ) {
fName = argv[1];
}

This is fine for C and C++ both, though in C++ it is recommended practice to use std::string instead.

C++ deprecated conversion from string constant to 'char*'

This is an error message you see whenever you have a situation like the following:

char* pointer_to_nonconst = "string literal";

Why? Well, C and C++ differ in the type of the string literal. In C the type is array of char and in C++ it is constant array of char. In any case, you are not allowed to change the characters of the string literal, so the const in C++ is not really a restriction but more of a type safety thing. A conversion from const char* to char* is generally not possible without an explicit cast for safety reasons. But for backwards compatibility with C the language C++ still allows assigning a string literal to a char* and gives you a warning about this conversion being deprecated.

So, somewhere you are missing one or more consts in your program for const correctness. But the code you showed to us is not the problem as it does not do this kind of deprecated conversion. The warning must have come from some other place.

Why is conversion from string constant to 'char*' valid in C but invalid in C++

Up through C++03, your first example was valid, but used a deprecated implicit conversion--a string literal should be treated as being of type char const *, since you can't modify its contents (without causing undefined behavior).

As of C++11, the implicit conversion that had been deprecated was officially removed, so code that depends on it (like your first example) should no longer compile.

You've noted one way to allow the code to compile: although the implicit conversion has been removed, an explicit conversion still works, so you can add a cast. I would not, however, consider this "fixing" the code.

Truly fixing the code requires changing the type of the pointer to the correct type:

char const *p = "abc"; // valid and safe in either C or C++.

As to why it was allowed in C++ (and still is in C): simply because there's a lot of existing code that depends on that implicit conversion, and breaking that code (at least without some official warning) apparently seemed to the standard committees like a bad idea.

Conversion from string literal to char* is deprecated

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.)

warning: conversion from string literal to 'char *' is deprecated

string literal 's type is const char[], and note that:

In C, string literals are of type char[], and can be assigned directly to a (non-const) char*. C++03 allowed it as well (but deprecated it, as literals are const in C++). C++11 no longer allows such assignments without a cast.

Then

1.What could go wrong with the char pointer?

As you said, char * make it possible to alter the string literal and leads to UB.

You could create an array initialized from the string literal, and then modify the array later, such as:

char type[] = "something"; // type will contain a copy of the string literal

2.Is const char * type = new char[20]; a good fix to get rid of the warnings?

No need to create a new array here, since you're only changing the value of the pointer itself, not the content it pointing to. You should just change the type of type to const char*,

const char * type = "";

deprecated conversion from string constant to 'char*' in c

This should be a warning (though you may have set your compiler to treat warnings as errors, which is often a good idea).

What you want is: char const *p = "hello"; instead.

Attempting to modify a string literal gives undefined behavior. The const prevents you from doing that by accident (i.e., code that attempts to write via the pointer won't compile, unless you remove the const qualifier, such as with a cast).

How to get rid of `deprecated conversion from string constant to ‘char*’` warnings in GCC?

I believe passing -Wno-write-strings to gcc will suppress this warning.



Related Topics



Leave a reply



Submit