when I do this: char* text; text = "Hello"; it works but what I'm really doing here is initialising a pointer of char and it can't hold the value "Hello", just the value of an address? If I do the same thing with int, it does not work why?
3 Answers
A literal string ends up being a pointer to your data section of your program so it is safe. But when you assign an int to a int*
it is telling the OS to use that memory location which is not safe

- 187,200
- 47
- 362
- 445
According to the C++ standard § 2.14.5/8
8 Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration
and section 2.14.5/14
14 After any necessary concatenation, in translation phase 7 (2.2), ’\0’ is appended to every string literal so that programs that scan a string can find its end.
"Hello"
is a narrow string literal, it produces
static const char __hello_str[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
In C++, inherited from C, is the concept of array-pointer equivalence, which in this context boils down to the fact that an array - or a string literal - will gladly decay into a pointer.
char* text;
text = "hello";
introduces a static, nul-terminated character array in the data section of the program, and assigns it's address to the char* variable pointer.
Technically, we're violating the const
ness of the array here, but many compilers allow this because of legacy C code. However, the C++ standard states in Annex C:
Subclause 2.14.5: The type of a string literal is changed from “array of char” to “array of const char.” The type of a char16_t string literal is changed from “array of some-integer-type” to “array of const char16_t.” The type of a char32_t string literal is changed from “array of some-integer-type” to “array of const char32_t.” The type of a wide string literal is changed from “array of wchar_t” to “array of const wchar_t.” Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument.
The legacy conversions were deprecated some time ago and have been illegal since C++11. The correct way to do this is:
const char* text;
text = "hello"; // correct
It's unclear whether you were trying to write
int* text;
text = "hello"; // error: incompatible types int* vs const char*
or whether you were trying to do something like:
const int a = 1;
int* ptr;
ptr = &a; // error: int* vs const int*.

- 23,617
- 2
- 42
- 74
-
1Re "The legacy conversions are deprecated and will in a future version of C++ will presumably become illegal.", conversion of a narrow string literal to `char*` has been invalid since C++11. – Cheers and hth. - Alf Jul 11 '16 at 00:57
-
Re the example
char* text; text = "Hello"; //! Not OK
The string literal has type char const [6]
, where the 6th char
value is a terminating zero-byte.
Converting that to char*
is invalid as of C++11 and later.
However, in C++98 and C++03 it was valid for backward compatibility with C. There was a special rule for string literals, that allowed dropping the const
. In C++11 and later you have to keep the const
-ness (which is more safe because modifying the literal is Undefined Behavior), i.e.
char const* text; text = "Hello";
Here the string literal decays to a char const*
pointer that points to the first char
value, and this pointer value is assigned to text
.
There is no such implicit conversion from int
to pointer value. But if you had an array of int
, that array would convert implicitly to pointer. E.g.,
int const a[] = { 2, 7, 1, 8, 2, 8, 1, 8, 2, 8};
int const* p = a;

- 142,714
- 15
- 209
- 331