423

そのため、私は非常に大きなコードベースに取り組んでおり、最近 gcc 4.3 にアップグレードしました。これにより、次の警告がトリガーされます。

警告: 文字列定数から 'char*' への非推奨の変換</p>

明らかに、これを修正する正しい方法は、次のようなすべての宣言を見つけることです

char *s = "constant string";

または次のような関数呼び出し:

void foo(char *s);
foo("constant string");

それらをconst charポインターにします。ただし、これは少なくとも 564 個のファイルに触れることを意味し、現時点では実行したくないタスクです。現在の問題は、私が で実行していることです-werror。そのため、これらの警告を抑える方法が必要です。どうやってやるの?

4

23 に答える 23

577

文字列リテラルを渡す関数は、 の代わりに型として"I am a string literal"使用する必要があります。char const *char*

何かを修正する場合は、正しく修正してください。

説明:

文字列リテラルを使用して、変更される文字列を初期化することはできません。型がconst char*. constness をキャストして後で変更することは未定義の動作であるため、文字列を変更するには、動的に割り当てられた文字列にconst char*文字列charをコピーする必要があります。charchar*

例:

#include <iostream>

void print(char* ch);

void print(const char* ch) {
    std::cout<<ch;
}

int main() {
    print("Hello");
    return 0;
}
于 2013-05-31T23:07:31.847 に答える
238

-Wno-write-stringsgcc に渡すと、この警告が抑制されると思います。

于 2008-09-12T18:22:10.030 に答える
73

同様の問題がありましたが、次のように解決しました。

#include <string.h>

extern void foo(char* m);

int main() {
    // warning: deprecated conversion from string constant to ‘char*’
    //foo("Hello");

    // no more warning
    char msg[] = "Hello";
    foo(msg);
}

これはこれを解決する適切な方法ですか?foo私はそれを受け入れるように適応させるためのアクセス権を持っていませんがconst char*、それはより良い解決策です(なぜならfooは変わらないからmです)。

于 2009-02-12T12:44:01.997 に答える
68

gcc の診断プラグマのサポートと、-W 警告オプションのリストを確認してください(変更:警告オプションへの新しいリンク)。

gcc の場合、こちらで#pragma warning説明されているようなディレクティブを使用できます。

于 2008-09-12T18:23:43.600 に答える
33

それがアクティブなコード ベースである場合でも、コード ベースをアップグレードする必要があるかもしれません。もちろん、手動で変更を行うことは現実的ではありませんが、この問題は 1 つのsedコマンドで完全に解決できると思います。ただし、私はそれを試していないので、塩の粒で次のことを考えてください.

find . -exec sed -E -i .backup -n \
    -e 's/char\s*\*\s*(\w+)\s*= "/char const* \1 = "/g' {} \;

これは (関数呼び出しを考慮していなくても) すべての場所を見つけるわけではありませんが、問題を軽減し、残りのいくつかの変更を手動で実行できるようにします。

于 2008-09-12T18:49:22.133 に答える
27

Makefile を変更する必要がないように、ファイル内でインラインで行う方法を次に示します。

// gets rid of annoying "deprecated conversion from string constant blah blah" warning
#pragma GCC diagnostic ignored "-Wwrite-strings"

後でできます...

#pragma GCC diagnostic pop
于 2011-11-15T17:47:40.553 に答える
25

交換

char *str = "hello";

char *str = (char*)"hello";

または、関数を呼び出している場合:

foo("hello");

これを

foo((char*) "hello");
于 2015-10-09T19:52:09.817 に答える
25

コンパイラ スイッチを使用できません。だから私はこれを変えました:

char *setf = tigetstr("setf");

これに:

char *setf = tigetstr((char *)"setf");
于 2009-08-21T02:14:26.480 に答える
15

それ以外の:

void foo(char *s);
foo("constant string");

これは機能します:

void foo(const char s[]);
foo("constant string");
于 2014-10-04T15:06:56.410 に答える
7

Test stringconst 文字列です。したがって、次のように解決できます。

char str[] = "Test string";

また:

const char* str = "Test string";
printf(str);
于 2010-03-17T10:18:26.257 に答える
3

型キャストだけを使ってみませんか?

(char*) "test"
于 2010-12-21T15:14:35.997 に答える
2

定数文字列から char ポインターへの型キャストを行います。

char *s = (char *) "constant string";
于 2014-07-15T12:36:13.200 に答える
0

を呼び出して、文字列定数から書き込み可能な文字列を作成することもできますstrdup()

たとえば、次のコードは警告を生成します。

putenv("DEBUG=1");

ただし、次のコードはそうではありません ( に渡す前に、ヒープに文字列のコピーを作成しますputenv)。

putenv(strdup("DEBUG=1"));

この場合 (そしておそらく他のほとんどの場合)、警告をオフにすることは悪い考えです。それには理由があります。もう 1 つの方法 (デフォルトですべての文字列を書き込み可能にする) は、潜在的に非効率的です。

コンパイラの言うことを聞いてください!

于 2009-05-05T20:49:48.093 に答える
0

-Wno-deprecated非推奨の警告メッセージを無視するオプションを使用しないのはなぜですか?

于 2008-10-26T05:53:56.303 に答える
0

この状況を参照してください。

typedef struct tagPyTypeObject
{
    PyObject_HEAD;
    char *name;
    PrintFun print;
    AddFun add;
    HashFun hash;
} PyTypeObject;

PyTypeObject PyDict_Type=
{
    PyObject_HEAD_INIT(&PyType_Type),
    "dict",
    dict_print,
    0,
    0
};

name フィールドを見てください。gcc では警告なしでコンパイルされますが、g++ ではコンパイルされます。理由はわかりません。

于 2010-08-24T02:14:08.547 に答える
0

g++ の -w オプションを使用するだけです

例:

g++ -w -o simple.o simple.cpp -lpthread

これは非推奨を回避するものではなく、端末に警告メッセージが表示されないようにするものであることを覚えておいてください。

本当に非推奨を避けたい場合は、次のように const キーワードを使用します。

const char* s="constant string";  
于 2012-06-08T16:43:11.687 に答える
0

助けてくれてありがとう。あちこちから選ぶと、この解決策が生まれます。これはきれいにコンパイルされます。コードはまだテストしていません。明日…多分…

const char * timeServer[] = { "pool.ntp.org" }; // 0 - Worldwide 
#define WHICH_NTP            0 // Which NTP server name to use.
...
sendNTPpacket(const_cast<char*>(timeServer[WHICH_NTP])); // send an NTP packet to a server
...
void sendNTPpacket(char* address) { code }

timeServer 配列には項目が 1 つしかありません。しかし、もっとあるかもしれません。メモリを節約するために、残りはコメントアウトされています。

于 2016-03-05T11:47:49.743 に答える
-1

今の問題は、私が -Werror で実行していることです

これはあなたの本当の問題です、IMO。(char *) から (const char *) に移動する自動化された方法をいくつか試すことができますが、機能するだけでなく、それらにお金をかけます。少なくとも一部の作業には人間が関与する必要があります。短期的には、警告を無視して (ただし、IMO は警告をオンのままにしておくか、修正されません)、-Werror を削除します。

于 2008-09-15T22:33:15.813 に答える
-1
PyTypeObject PyDict_Type=
{ ...

PyTypeObject PyDict_Type=
{
  PyObject_HEAD_INIT(&PyType_Type),
                     "dict",
                     dict_print,
                     0,
                     0
}; 

name フィールドを見てください。gcc では警告なしでコンパイルされますが、g++ ではコンパイルされます。理由はわかりません。

ではgcc (Compiling C)、-Wno-write-strings がデフォルトでアクティブになっています。

in g++ (Compiling C++)-Wwrite-strings はデフォルトでアクティブです

これが、異なる動作がある理由です。のマクロを使用すると、Boost_pythonこのような警告が生成されます。したがって-Wno-write-strings、常に使用するため、C ++をコンパイルするときに使用します-Werror

于 2012-05-14T13:55:13.170 に答える