deprecated conversion from string constant to 'char*'

- Experts,

I know that the conversion from string constant to char* is deprecated in cpp. So to initialize a char* first we have to reserve space of the char array e.g: b[]="hola" and the you can initialize the char pointer to b.

However I do not understand why this is allowed then:
1
2
3
4
5
6
7
8
9
int main(){
   union{
	int a;
	const char* p;
	};
   a = 1;
   p = "Jennifer"; 
   cout <<p;
}


Why does the cpp compiler not complain for this case? We are also doing a conversion from string constant to char*. Aren't we?

Is there any other way of doing the same of anonymous unions in cpp?

Thanks.
You are not allowed to modify the string. That's why you should not use char*. Using const char* on the other hand is perfectly fine because it protects you from modifying the string accidentally.

1
2
const char* p = "Jennifer"; 
p[0] = 'D'; // error: assignment of read-only location ā€˜* pā€™ 
Last edited on
> I know that the conversion from string constant to char* is deprecated in cpp.

It is not allowed in standard C++; a conforming implementation should generate an error.
(This conversion used to be deprecated in legacy C++).
http://coliru.stacked-crooked.com/a/96e0b76df4b2cd65


> Why does the cpp compiler not complain for this case?
> We are also doing a conversion from string constant to char*. Aren't we?

No. Here we are performing a conversion from a string literal to const char*.

The type of the literal "Jennifer" is 'array of 9 const char'. The literal is an object with static storage duration.

const char* p = "Jennifer"; // initialisation of p involves an implicit array-to-pointer conversion
I understand, thanks!

Regarding what @Peter87 said:
"You are not allowed to modify the string"

Is there a reason why the standard C++ not allow the conversion from string literal to char*?

It is however possible to modify the string doing the following:
1
2
3
char a[]="hola";
char * p;
p=a;

Now I am able to access to the elements of the array and modify it. What is to say I am allowed to modify the string. So somehow cpp allows to modify the string...
This line here is more complicated than it looks.
 
    char a[]="hola";
It defines an array of 5 characters, which you are allowed to modify. It assigns the initial value "hola" to that array.

But in the other example,
 
    const char * p = "hola"; 
there is no array. The only thing which is defined is a pointer. So you cannot alter the contents of the array because there is no array. The pointer is assigned an initial value, it points to a read-only string, which is something separate.

If you wanted a pointer to an array which you can modify, then you could do something like this:
1
2
3
    char array[10] = "";  // define an array, initial value empty string(for example).

    char * p = array;     // define a pointer to that array 
Last edited on
The characters are stored somewhere in memory. When you assign a string literal to a pointer all that is happening is that the pointer is set to point to the first character in the string. If you were allowed to modify the characters of the string just imagine what would happen if the same line of code was executed again later on. You would not get the original string but instead the modified one, which would have been very unexpected.

I cannot think of a very good example, but just to demonstrate what i mean, here is a program that use a function that replaces the first occurrence of x with a number (only works for 0-9). If this program had been valid the function would have found the x and replaced it with a 0 the first time it was called, but the second time it would not have found an x, because it had already been replaced, so the program ends up printing the same message five times.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <cstring>

void replace_x(char* msg, int x)
{
	char* xPtr = std::strchr(msg, 'x');
	if (xPtr != nullptr)
	{
		*xPtr = '0' + x;
	}
}

int main()
{
	for (int i = 0; i < 5; ++i)
	{
		char* msg = "The value of i is x.\n";
		replace_x(msg, i);
		std::cout << msg;
	}
}
The value of i is 0.
The value of i is 0.
The value of i is 0.
The value of i is 0.
The value of i is 0.

The program could easily be "fixed" by declaring msg as an array in main().

 
char msg[] = "The value of i is x.\n";

This will copy the whole string each time msg is initialized (five times), so the function doesn't actually modify the original string that the string literal gives you but instead it modifies a copy that is stored in the local array.
Last edited on
Thank you I have now a clear idea
Topic archived. No new replies allowed.