I agree completely with the other answers, I just want to add that g++ (at least version 4.4) actually catches these deprecated conversions as warnings at any warning level (if previous versions do not do this by default, probably you have to raise the warning level):
#include <iostream>
using namespace std;
void WithConst(const char * Str)
{
cout<<Str<<endl;
}
void WithoutConst_NoEdit(char * Str)
{
cout<<Str<<endl;
}
void WithoutConst_Edit(char * Str)
{
*Str='a';
cout<<Str<<endl;
}
int main()
{
WithConst("Test");
WithoutConst_NoEdit("Test");
WithoutConst_Edit("Test");
return 0;
}
matteo@teoubuntu:~/cpp/test$ g++ --version
g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
matteo@teoubuntu:~/cpp/test$ g++ -O3 lit_const_corr.cpp -o lit_const_corr.x
lit_const_corr.cpp: In function ‘int main()’:
lit_const_corr.cpp:24: warning: deprecated conversion from string constant to ‘char*’
lit_const_corr.cpp:25: warning: deprecated conversion from string constant to ‘char*’
matteo@teoubuntu:~/cpp/test$ g++ -O3 -Wall lit_const_corr.cpp -o lit_const_corr.x
lit_const_corr.cpp: In function ‘int main()’:
lit_const_corr.cpp:24: warning: deprecated conversion from string constant to ‘char*’
lit_const_corr.cpp:25: warning: deprecated conversion from string constant to ‘char*’
matteo@teoubuntu:~/cpp/test$ g++ -O3 -Wall -Wextra -ansi -pedantic lit_const_corr.cpp -o lit_const_corr.x
lit_const_corr.cpp: In function ‘int main()’:
lit_const_corr.cpp:24: warning: deprecated conversion from string constant to ‘char*’
lit_const_corr.cpp:25: warning: deprecated conversion from string constant to ‘char*’
Moreover, there's some interesting thing going on under the hood: if I compile it without optimization, it "just does what the code says", so it crashes, since it tries to write to a read-only memory location:
matteo@teoubuntu:~/cpp/test$ g++ -Wall -Wextra -ansi -pedantic lit_const_corr.cpp -o lit_const_corr.x
lit_const_corr.cpp: In function ‘int main()’:
lit_const_corr.cpp:24: warning: deprecated conversion from string constant to ‘char*’
lit_const_corr.cpp:25: warning: deprecated conversion from string constant to ‘char*’
matteo@teoubuntu:~/cpp/test$ ./lit_const_corr.x
Test
Test
Segmentation fault
but, if you turn on the optimizer, there's no crash:
matteo@teoubuntu:~/cpp/test$ g++ -O3 -Wall -Wextra -ansi -pedantic lit_const_corr.cpp -o lit_const_corr.x
lit_const_corr.cpp: In function ‘int main()’:
lit_const_corr.cpp:24: warning: deprecated conversion from string constant to ‘char*’
lit_const_corr.cpp:25: warning: deprecated conversion from string constant to ‘char*’
matteo@teoubuntu:~/cpp/test$ ./lit_const_corr.x
Test
Test
Test
I suppose that this is due to some magic optimization trick, but I don't understand why is it applied; any idea?
Addendum
When I declare a char* foo = "bar" it actualy complains. But when I declare char foo[] = "bar" it doesn't
Hey, be careful not to confuse the two things: with
char * foo = "bar";
you are declaring a pointer to char, and you assign to it the address of the literal "bar", which is actually stored in some read-only memory location (usually it's a part of the executable that is mapped in memory).
Instead, with
char foo[]="bar";
you are declaring and allocating RW memory (on the stack or somewhere else, depending from the context) for an array of chars, which is initialized with the "bar" value, but it is not related to the string table at all, and it's perfectly legit to change that string.