Reputation: 425
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
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
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
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