nTIAO
nTIAO

Reputation: 425

A value of type "const char*" cannot be used to initialize an entity of type "char *"

I have a code like this but I keep receiving this error :

A value of type "const char*" cannot be used to initialize an entity of type "char *"

What is going on?
I have read up on the following threads but have not been able to see any result to my answer as all of them are either from char to char* or char* to char:
Value type const char cannot be used to initialize an entity of type char*
Value of type char* cannot be used to initialize an entity of type "char"

#include <iostream>;
using namespace std;

int main() {
    int x = 0; //variable x created
    int cars (14);//cars is created as a variable with value 14
    int debt{ -1000 };//debt created with value 1000
    float cash = 2.32;
    double credit = 32.32;
    char a = 'a';//for char you must use a single quote and not double
    char* sandwich = "ham";
    return 0;
}

I am using Visual Studio Community 2017

Upvotes: 34

Views: 141600

Answers (3)

Ravi Tiwari
Ravi Tiwari

Reputation: 962

Your code (and underlying assumption) is valid pre C++11 standard.


String literals (e.g. "ham") since C++11 are of type const char* (or const char[]) if you will instead of char * they used to be. [Always read specs for breaking changes!!!]
Hence the warning in VS 2017. Change the compiler version to pre C++11 version and you will be amazed.

This has subtle nuances and can cause frustrating debug sessions

// C++11 or later

auto c = "Rowdie"; 
// c has type const char*, can't use c to modify literal
c[0] = 'H'; // illegal - CTE

// -vs- 

char * d = "Rowdie";
d[0] = 'H';
cout << d; // outputs "Howdie"

Also another example is auto return type from functions

auto get_literal() {
  // ... function code
  return "String Literal";
}

// and using value later
char* lit = get_literal(); // You get same error as const char* cannot be init to char*

Upvotes: 1

Davislor
Davislor

Reputation: 15164

That is correct. Let’s say you had the following code:

const char hello[] = "hello, world!";
char* jello = hello; // Not allowed, because:
jello[0] = 'J'; // Undefined behavior!

Whoops! A const char* is a non-const pointer to const char. If you assign its value to a non-const char*, you’ve lost its const property.

A const pointer to non-const char would be a char* const, and you can initialize a char* from that all day if you want.

You can, if you really want, achieve this with const_cast<char*>(p), and I occasionally have, but it’s usually a sign of a serious design flaw. If you actually get the compiler to emit instructions to write to the memory aliased by a string constant, you get undefined behavior. One of the many things that might go wrong is that some implementations will store the constant in read-only memory and crash. Or the same bytes of memory might be re-used for more than one purpose, because after all, we warned you never to change it.

By the way, the rules in C are different. This is solely for backward-compatibility with early versions of C that did not have the const keyword, and you should never write new code that uses a non-const alias to a string constant.

Upvotes: 34

Justin Randall
Justin Randall

Reputation: 2278

You need to make your string literal type const because in C++ it is a constant array of char, unlike C where it is just an array of char. You cannot change a string literal, so making it const is preferred in C++ for extra safety. It is the same reason you have to use an explicit cast when going from const char* to char*. It's still technically "allowed" in C++ since it is allowed in C, which is why it's just a warning. It's still bad practice to do so. To fix the warning, make it const.

const char* sandwich = "ham";

Upvotes: 19

Related Questions