char array and pointer to char array assignment

In both programs I am trying to assigning pointer to char to that char arry.
In second case program correctly. but in first case showing error.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

#include<iostream>
using namespace std;

const char z[]="Blank";
void callthis(const char* m);

int main(){

	callthis("Test");
	
	return 0;
}

void callthis(const char* m){
	z=m;	// error C2440: '=' : cannot convert from 'const char *' to 'const char [6]'
}

 
/*
#include<iostream>
using namespace std;

void callthis(const char t[]);

const char* x = "Blank";			// Blank pointer to char

int main(){	
	
	callthis("Test");
	
	return 0;
}

void callthis(const char t[]){	
	
	t=x;		// OK
}

*/  
An array is not a pointer so you can't assign the pointer to the array. If you want to copy the chars you can use std::strcpy function (assuming the chars represents a null terminated string, aka "C string", which is the case in your program).

 
std::strcpy(z, m);

http://www.cplusplus.com/reference/cstring/strcpy/
Also check the fact that it is a constant.

Aceix.
then how does second program working ?
I didn't THINK the second one should be OK since it is assigning a value to a constant in the body... so I set up the program in my VS environment. When I mousover the z (with a red line under it) in the first program, it says: "const char z[6] = "Blank" Error: expression must be a modifiable value".

I got rid of all const labels, and it says the same thing. After a lot of looking, I found the answer SORT of hidden when I tried to run the first program. Read on and you should see this too in VS2010 in the log:

1
2
3
1>c:\users\nick\documents\visual studio 2010\projects\datastructuresmalik\ch. 1\quickpractice\quickpractice\dognames.cpp(15): error C2440: '=' : cannot convert from 'char *' to 'char [6]'
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(153,5): error MSB6006: "CL.exe" exited with code 2.
1>          There are no conversions to array types, although there are conversions to references or pointers to arrays


So that last line there means that conversion can go one way, but simply not the other. Ta-da! But still, it is strange to me that you state it is constant but can change the value in the second program.
Last edited on
I will upload compiled screen image file and output file.
can someone tell me how to upload the file ?
santosh anantwal wrote:
can someone tell me how to upload the file ?

You can upload images to imgur.com (or some other image hosting service) and link to it in your post, or why not copy paste the error message here?

santosh anantwal wrote:
then how does second program working ?

Note that t is a pointer. It might look like an array but it's a pointer. Both of these are exactly the same:
1
2
void callthis(const char* t);
void callthis(const char t[])

I suspect you have made a mistake because you are assigning x to t which is kind of pointless because the t pointer will stop to exist after the function has ended. You probably meant to assigning t to x: x=t;

Note that in the second program the pointer x is not constant. It is what the pointer points to that is const. To make x const you would declare it as: const char* const x = "Blank";
Last edited on
@ Peter87 (6160)

I know that t pointer will stop to exist after function has ended.
but if char array and pointer are same and if
t=x is possible in function body, then why not z=m ?

regarding with constant pointer and pointer to constant, I know both, but my focus is on assignment.

Here is second program compilation image
"http://imgur.com/Ysk870G">

and here is output
"http://imgur.com/2GLRYum">
santosh anantwal wrote:
but if char array and pointer are same and if
t=x is possible in function body, then why not z=m ?

Because an array is not a pointer.
ok
but my question is,
if t=x is possible in function body, then why not z=m ?

Here is simplified version of above two programs combined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
using namespace std;

void callthis(const char b[]);

const char* temp="Second_Test";

int main(){
    
	callthis("First_Test");
    	 //const char a[]="first";
	 //a=temp;
    	 //cout << "a is: " << a << endl;

	return 0;
}

    void callthis(const char b[]){

	b=temp;
    	cout << "b is: " << b << endl;
    }

OK, I thought I gave you the answer but perhaps it was either wrong or not clear enough? Here it is again.

The output from the log when the program fails to build explicitly states that:
1) There are no conversions to array types, and
2) There are conversions to references or pointers to arrays.

Upon a little more examination, a search for error code C2440 is referenced here: http://msdn.microsoft.com/en-us/library/sy5tsf8z.aspx

That page states in the first part that a literal string in C++ is a const char array. There is no conversion from a const char pointer to a const char array (which is the messsage you got). HOWEVER, a conversion vice versa is doable; in other words, a const char array can be converted to a const char pointer, and that is the simplest answer you're likely to get.

Again, a literal string is a const char array. A const char array can be converted to a const char pointer. But a const char pointer is not a literal string (a const char array), nor can it be converted into one.

:)
Last edited on
It would be very clear if you give examples from above program

1) There are no conversions to array types, and
2) There are conversions to references or pointers to arrays.

3) There is no conversion from a const char pointer to a const char array
4) a const char array can be converted to a const char pointer
5) a literal string is a const char array.
6) A const char array can be converted to a const char pointer
7) But a const char pointer is not a literal string (a const char array)
OK, but I want you to know that I came up with some different conclusions, way easier ones. I also want to say here that I don't know everything obviously, but that I am piecing together a solution from different sources. Enjoy my train of thought. This one's a doozy.

***If anyone wants the final answer, just go down to the last code window***


Here is a much less complicated program I came up with, similar to yours, and throwing the same error.

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

int main(){

const char* string1 = "string1";
const char string2[] = "string2";

string1 = string2;  // This one works fine.
string2 = string1;  // If you hover over string2 (should be underlined by red), it will tell you
                            // that the expression must be a modifiable value, but it gives the same
                            // error when you attempt compilation: C2440

std::cin.get();

return 0;

}


I tried different things to see what else I could find out, so I tried to make string2 = some other string instead. string2 was still underlined with the same message, and the compiler throws an error saying "cannot convert from const char [one size] to const char [another size]", as I tried strings of different sizes. So I matched the number of letters, like here:

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

int main(){

const char* string1 = "string1";
const char string2[] = "string2";

string1 = string2;

string2 = "Vlad567"; // string2 hover-over displays exactly:
// "const char string2[8] = "string2"
// Error: string must be a modifiable lvalue (lvalue not a typo)

string2 = string1;  // same hover-over message

std::cin.get();

return 0;

}


When compile attempted, this comes out:
1
2
error C2106: '=' : left operand must be l-value  (at line string2 = "Vlad567";)
error C2440: '=' : cannot convert from 'const char *' to 'const char [8]' (at line string2=string1;)


I looked up that first error, which is a different kind, and found this page: http://msdn.microsoft.com/en-us/library/wxy5f14h.aspx

Which gives this example of what can throw this error, namely something like:
1 = a;

SOOO what I am getting from this is that once a const string array is defined, that is it. It cannot be changed period. Whenever you see it again, you might as well type in the literal string it represents.

On the other hand, when a const char pointer is defined, it CAN be changed. Check out this other forum topic: http://www.cplusplus.com/forum/beginner/10602/

There, kbw states that const char * is a pointer to a constant string. A const char * can point to a different string, but the string it is currently pointing to cannot change.

I hope this has answered your question and gave some clarification.

Referring to your original code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<iostream>
using namespace std;

const char z[]="Blank";  // z is now set as a constant char array - it CANNOT be changed.
void callthis(const char* m);

int main(){

	callthis("Test");
	
	return 0;
}

void callthis(const char* m){  // m points to the constant char array "Test"
	z=m;	// error C2440: '=' : cannot convert from 'const char *' to 'const char [6]'
}

 
/*
#include<iostream>
using namespace std;

void callthis(const char t[]);

const char* x = "Blank";			// x POINTS to constant string "Blank"

int main(){	
	
	callthis("Test");
	
	return 0;
}

void callthis(const char t[]){	// const char t[] = "Test".....OK, I lose.  See comment at end.
	
	t=x;		// OK
}

*/  


I still couldn't figure it out. So when you hover-over t in the above statement, it says guess what? It IS a const char *. I don't know why. It seems like it should be read as a literal string, but my guess is that when you are passing the string as an array, since you are not passing it by address, t is simply a pointer to the original string you had listed.

In other words, a pass by value is the same thing as pointing to what is being passed, essentially meaning it is a pointer to the array, which MEANS that the line t=x is legal. So NOW, here is your original code again with attached final comments. Enjoy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include<iostream>
using namespace std;

const char z[]="Blank";   // z is set to a constant character array.  It cannot change period.
void callthis(const char* m);

int main(){

	callthis("Test");
	
	return 0;
}

void callthis(const char* m){  // m is a pointer to a the const character array "Test"
	z=m;	// error C2440: '=' : cannot convert from 'const char *' to 'const char [6]'
// Here, const char [6] = const char * is not legal.
}

 
/*
#include<iostream>
using namespace std;

void callthis(const char t[]);

const char* x = "Blank";			// x is a pointer, pointing to a constant char array with values "Blank"

int main(){	
	
	callthis("Test");     // literal string passed
	
	return 0;
}

void callthis(const char t[]){	// This is the key.  Passed by value which essentially means this is a POINTER to the original data being passed - "Test" - and NOT that actual string.  
	
	t=x;		// OK  // when you hover-over t in this statement, says "const char * t"
//  And that's the game!  Here, const char * = const char * is perfectly legal.
}

*/  
Last edited on
I repeat what I said earlier. t is a pointer. These two function declarations are 100% equivalent.
 
void callthis(const char t[]); // t is a pointer 
 
void callthis(const char* t);  // t is a pointer 

I understand this can be confusing because when you declare an array these two ways of writing it are not equivalent:
 
const char x[] = "Blank"; // x is an array 
 
const char* x = "Blank";  // x is a pointer 
Actually, above you said an array is not a pointer, but also the same thing as this post. You didn't say WHY const char t[] in the function call is a pointer, which is why we remained confused.
Thanks everybody.
especially nickeeromo. your explanation of WHY things happen that way, was most important for me.
and Peter87's last 4 lines summarized everything.
Topic archived. No new replies allowed.