1. ホーム
  2. C言語

警告: 非推奨の文字列定数から 'char *' への変換[-Write-strings] 解決法

2022-02-21 05:33:19

Linux で GCC のバージョンが高い場合、コードのコンパイルに問題が発生する可能性

まずこの関数のプロトタイプを見ることで問題が発生します。

void someFunc(char *someStr);

この関数呼び出しをもう一度見てみましょう。

someFunc("I'm a string!") とします。

この2つを組み合わせて、最新のg++でコンパイルすると、タイトルの警告が表示されます。

なぜ?char *の意味は、「文字列をくれ、それを修正したい」であることがわかりました。

そして理論的には、関数に渡すリテラル定数は変更できない。

ですから、より論理的な方法として、引数の型をconst char *に変更することができます。

この型が言う意味は、「文字列をくれ、それを読めればいいんだ」ということです。

これを少し拡張するのは自然なことだ。

リテラル定数と文字列変数の両方を渡したい場合はどうすればよいのでしょうか。オーバーロード

実験する

文字列定数から「char *」への非推奨変換などの警告の詳細説明

char* 型の変数で、あるときは文字列を指し、あるときは別の文字列を指すようにしたいとします。開始時のコードは次のようになります。



char *msg;



msg = "こんにちは"。



msg = "good-bye"。

コンパイラはこのコードに対して、"deprecated conversion from string constant to 'char *'"、つまり、文字列の内容を変更する能力がないという警告を2つ出しています。もし、このようなコードが書かれていた場合、例えば



char *msg = "こんにちは"。



*msg = 'j';



printf( "%s/n", "hello" );

コンパイラは、msgが指すものを "hello" から "jello" に実際に変更してしまいますが、正しい解決策は msg を以下の場所で不変の文字列へのポインタとして宣言することです。



const char *msg;



msg = "こんにちは"。



msg = "good-bye"。

このコードはコンパイルに成功し、msgが指す値を希望通りに変更しますが、もしポインタを.



*msg = 'j';



文字列定数は変更できないため、エラーが発生します。

次のコードに注目してください。警告もエラーもなくコンパイルされています。



const char *msg;



char buf[ 10 ]; // char *buf は使用できないことに注意。



sprintf( buf, "%03d/n", 7 );



msg = buf;

buf は定数として宣言されていないため、内容を変更することが可能である。この場合、msg は "007/n" という文字列を指すことになります。このようなステートメント



*buf = 'x';



は正しくコンパイル、実行されますが



*msg = 'x';



msg が指すコンテンツは変更できないため、警告が発生します。

もう一つの方法は、強制変換を使うことです。強制変換を使うということは、何が起こるかを正確に知っていて、コンパイラに判断を仰ぐ必要がないということです。例えば、次のコードは警告を発生させません。



char *msg;



msg = (char *) "こんにちは"。

しかし、一度強制変換を使用すると、コンパイラはエラーや警告を出さずに次の文もコンパイルします。



*msg = 'j';

このエラーは常に存在しますが、実行時まで検出されません。その時にエラーを見つけるのは、コンパイラが警告してくれるよりもずっと面倒なことです。だから、文字列の強制変換は使わない方がいい。

定数ポインタ

定数の位置によって、4つのケースが考えられます。



const char* const msg_0;



const char *msg_1;



char* const msg_2;



char *msg_3;

msg_0 は const 型文字列への定数ポインタです。この宣言では、msg_0 のポインタが初期化されていないため、後続の文が mg_0 に値を代入できないので、コンパイラから警告が出されます。



const char const *msg_0 = "こんにちは";



は正常にコンパイルされますが



*msg_0 = 'j'; または



msg_0 = "さようなら"はエラーになります。

msg_1 は const 型文字列または mutable 型文字列を指しますが、指した文字列の内容を変更することはでき ません。

msg_2 をコンパイルすると、msg_0 と同じエラーが発生します。ポインタは定数ですから、最初に値が割り当てられるはずです。ポインタに値が割り当てられていれば、ポインタの指す文字列の内容を変更する ことができます。



char buf[ 10];



char * const msg_2 = buf;



このコードでは、msg_2 は buf[0] を指し、常にこのアドレスを指し、変更されることはありま せん。

msg_3 については、あまり説明することはないでしょう。ポインタを変更することもできますし、ポインタの指す先を変更することもできます。



--------------------- 



著者:xyy410874116 



出典 CSDN 



元記事: https://blog.csdn.net/xyy410874116/article/details/6397549 



著作権について これはブログ主のオリジナル記事です。ブログ記事へのリンクを貼ってください