私は他の回答に完全に同意します。g++(少なくともバージョン4.4)が実際にこれらの非推奨の変換を任意の警告レベルで警告としてキャッチすることを追加したいと思います(以前のバージョンがデフォルトでこれを行わない場合は、おそらく警告を上げる必要がありますレベル):
#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*’
さらに、内部で興味深いことが起こっています。最適化せずにコンパイルすると、「コードの指示どおりに実行される」ため、読み取り専用メモリの場所に書き込もうとするため、クラッシュします。
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
ただし、オプティマイザをオンにすると、クラッシュは発生しません。
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
これは魔法の最適化のトリックによるものだと思いますが、なぜそれが適用されるのかわかりません。何か案が?
補遺
char * foo = "bar"を宣言すると、実際には文句を言います。しかし、char foo [] = "bar"と宣言すると、宣言されません。
ねえ、2つのことを混同しないように注意してください:と
char * foo = "bar";
charへのポインタを宣言し、それにリテラル「bar」のアドレスを割り当てます。これは、実際には読み取り専用のメモリ位置に格納されています(通常、メモリにマップされる実行可能ファイルの一部です)。代わりに、
char foo[]="bar";
「bar」値で初期化されるcharの配列に対して、RWメモリ(スタック上またはコンテキストに応じて他の場所)を宣言して割り当てていますが、文字列テーブルとはまったく関係ありません。その文字列を変更することは完全に合法です。