警告: 非推奨の文字列定数から 'char *' への変換ソリューションです。
リナックス 環境 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 では、あまり説明することがありません。ポインタを変更し、そのポインタが指すものを変更することができます。
関連
-
シェルスクリプト二項演算子期待値エラー
-
fatal:'origin' は git リポジトリでないようです fatal:Could not read from the remote repository
-
ARM Linuxの割り込みメカニズム解析
-
SocketExceptionです。ブロークン・パイプ・エラーの可能性
-
AttributeError: モジュール 'tensorflow' には 'get_default_graph' という属性がありません。
-
ソケットプログラミング、エラーの原因 ソケット以外でのソケット操作
-
セグメンテーションフォールト(コアダンプ)の解決法
-
linuxのセグメンテーション障害
-
テキストファイルのビジー状態解消
-
実行中のデータノードが1つあり、この操作で除外されるノードはありません。 エラー
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
ssh@host:""ssh スイッチで他のマシンで複数のコマンドを実行する。stdin はターミナルではないので、擬似ターミナルは割り当てられない。
-
linux シェルスクリプト実行エラー:不正な置換
-
LNMP nginx1.4.6+php5.5.11+mysql5.6.17+mecache+opcache コンパイルとインストール+opcacheパラメータ詳細+opcacheビジュアルPHPページコード
-
解決策 VMの初期化中にエラーが発生しました java/lang/NoClassDefFoundError: java/lang/Object
-
Haproxy の「502 Bad Gateway サーバーが無効または不完全な応答を返しました」を解決する。
-
mysqldumpです。エラーが発生しました。1066: ユニークなテーブル/エイリアスではありません
-
socket.errorを解決する。[Errno 98] アドレスが既に使用されている問題
-
テキストファイルのビジー状態
-
linux ubuntu 'string' はこのスコープで宣言されていない Parse
-
Werror=unused-but-set-variableエラーの解決法