警告: 非推奨の文字列定数から 'char *' への変換[-Write-strings] 解決法
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
著作権について これはブログ主のオリジナル記事です。ブログ記事へのリンクを貼ってください
関連
-
undefinedMakefile:***セパレータがありません。
-
Cプログラムの単純なエラー [エラー] ldは1終了ステータスを返した
-
複数形使用時:'**'の前にイニシャライザを置く解決策を期待。
-
エラーが発生しました。#79: 型指定子が必要です
-
struct と typedef struct を徹底的に理解する
-
libstdc++-6.dll が見つからないため、コードの実行を継続できません。プログラムを再インストールすると、この問題が解決する場合があります。
-
変数、配列、構造体におけるC言語の代入
-
c 言語エラー警告: 複数文字文字定数
-
Cエラー:構造体でも組合でもないものにメンバ 'xxx' を要求しています。
-
C C++プログラムのランタイムプログラムは、書き込みエラーのためにDebug/1.exeを開くことができません。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
すでに#.objで定義されているものを修正する。
-
エラー LNK2005: _main は first.obj で既に定義されています。
-
デバッグエラー MSB3073: :VCEnd がコード Solution で終了した
-
エラーが発生しました。#852: 式は完全なオブジェクト型へのポインタでなければならない
-
free(): 次のサイズが無効 (fast): 0x0000000000aa4430 問題あり
-
Cコンパイル警告:代入がキャストなしで整数からポインタを作成する
-
Linuxプログラムにおけるセグメンテーションフォールト(コアダンプ)の一般的な解決方法
-
0xffffffとは何ですか?