web-dev-qa-db-ja.com

文字列リテラルから「char *」への非推奨の変換

次のような文字列の配列を宣言するプログラムがあります。

char *colors[4] = {"red", "orange", "yellow", "blue"};

しかし、上記のコンパイラ警告が表示されます。コンパイルされますが、非推奨ではない方法を使用します(ある場合)。私はそれが何を意味するのかを調べようとしましたが、私はそれを理解できないようです。 「char」が機能する前に「const」を使用すると聞いたことがありますが、エラーの意味を誰かが説明できると助かります。ありがとう。

55
Matt

入力する文字列「red」、「organge」などは「リテラル」です。これらはプログラムコード自体の中で定義されているためです(ディスク、ユーザー入力/ stdinなどから直接読み取られません)。

これは、任意の時点でcolorsに書き込もうとすると、元の入力に直接アクセスして編集することを意味します。これにより、望ましくない実行時エラーが発生します。

Constとして宣言すると、このポインターへの書き込みを決して試行せず、このような実行時エラーを回避できます。

const char *colors[4] = {"red", "orange", "yellow", "blue"};

実行時にこれらの値を編集したい場合は、まず文字列をコピーする必要があります。

75
d_inevitable
"red", "orange", "yellow", "blue"

これらは定数文字列です。定数文字列への非constポインターの作成は間違っているため、警告が表示されます。現時点では警告が表示されていますが、c ++ 03では非推奨であり、c ++ 11では禁止されているため、エラーになるはずです。

10
BЈовић

これらの答えはすべて正しいです。

引数として文字の配列を必要とする関数があり、この引数を次のように渡す場合:

foo ("bar");

同じ警告が表示されます。この場合、次のいずれかを実行できます。

1)最初の回答で説明したように、次のように変更します。

void foo (char[] str) { printf(str); }

const char param[] = "bar";
foo (param);

2)次のようなC++標準文字列の使用を検討してください。

void foo (std::string theParam) { std::cout << theParam; }

foo ("bar");

私見、実際のパフォーマンスの問題が関係しておらず、Cライブラリを使用していない限り、または他の人が使用するC++ライブラリを作成している場合は、C++の不変文字列とその機能セットを使用する必要があります。

Unicodeが要件である場合、C++でのサポートは here で説明されているように「ひどい」です。 この質問 は、いくつかの手がかりを提供します(主に、IBM ICUライブラリ)を使用します。プロジェクトに既にQtがある場合、QStringは、 Gettextも同様です。

4
tiktak