-3

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?

gigi
  • 669
  • 6
  • 11

3 Answers3

1

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

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
1

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 constness 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*.
kfsone
  • 23,617
  • 2
  • 42
  • 74
0

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;
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331