1. ホーム
  2. Qt

警告: 非推奨の文字列定数から 'char *' への変換ソリューションです。

2022-02-21 08:18:50

リナックス 環境 GCC 上位バージョンでのコンパイル時に発生する可能性のある問題

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

void someFunc(char *someStr);

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

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

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

なぜ?それは、以下のことが判明したからです。 の後ろは、「文字列をくれ、それを修正したいんだ」という意味です。

そして、理論的には 関数に渡すリテラル定数は、変更することができません .

つまり、より調和の取れたアプローチは、次のようになります。 パラメータタイプを <スパン const char * .

この型文に込められた意味は 文字列をくれ、それを読むだけでいいんだ。

少し伸ばすのは当然です。

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

実験する

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







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



char *msg;



msg = "こんにちは"。



msg = "グッド-バイ"。







コンパイラはこのコードに対して、"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 = "グッド-バイ"。







このコードは正常にコンパイルされ、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 では、あまり説明することがありません。ポインタを変更し、そのポインタが指すものを変更することができます。