2011-10-25 28 views
13

可能性の重複:
Deprecated conversion from string constant to char * errorC++ - 'のchar *' に定数文字列から非推奨の変換

は、私が(このコードは、2004年に右行って、今日古いC++のコードを実行しようとした:) 。

... 
#include <error.h> 

int error_handler::error_number = 0; 
int error_handler::message_number = 0; 
int error_handler::debug_number = 0; 
int error_handler::Q_debug  = 1; 
int error_handler::object_number = 0; 
int error_handler::tab   = 33; 

error_handler::error_handler(const char *name, char *error_file_name) 
{ 
    errname = new char [filename_size]; 
    strcpy(errname,error_file_name); 

    errfile.open(errname,ios::app); 

    if (!errfile) 
    { 
     cerr << "error_handler: cannot open error file " << errname << endl; 
     exit(1); 
    } 

    errfile.close(); 

    my_name = name; 
    object_number++; 

    debug(""); 
} 


void error_handler::error(char* s1, char* s2, char *s3, char *s4) 
{ 
    error_number++ ; 

    errfile.open(errname,ios::app); 
    errfile.setf(ios::left); 

    errfile << "FAILURE: " << setw(tab) << my_name << "  " << s1 << ' ' << s2 
    << s3 << s4 << endl; 

    errfile.close(); 

exit(1); 
} 
... 

そして "error.h" ファイルのソース: "error.C" ファイルの

make[1]: Entering directory `/home/thehost/Plocha/lpic-1.3.1/lpic/src' 
source='error.C' object='error.o' libtool=no \ 
depfile='.deps/error.Po' tmpdepfile='.deps/error.TPo' \ 
depmode=gcc3 /bin/bash ../../config/depcomp \ 
g++ -DHAVE_CONFIG_H -I. -I. -I../.. -g -O2 -Wno-deprecated -g -O2 -c -o error.o `test -f 'error.C' || echo './'`error.C 
error.C: In constructor ‘error_handler::error_handler(const char*, char*)’: 
error.C:49:7: error: ‘cerr’ was not declared in this scope 
error.C:58:11: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite- strings] 
error.C:58:11: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite- strings] 
error.C:58:11: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite- strings] 
error.C:58:11: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite- strings] 
make[1]: *** [error.o] Error 1 
make[1]: Leaving directory `/home/thehost/Plocha/lpic-1.3.1/lpic/src' 
make: *** [all-recursive] Error 1 

が出典:

... 
using namespace std; 

class error_handler { 
static int error_number; 
static int message_number; 
static int Q_debug; 
static int debug_number; 
static int object_number; 
const char *my_name; 

char  *errname; 

ofstream errfile; 
static int tab; 
public: 
error_handler(const char *, char *error_file_name); 


void error(char* s1, char* s2="", 
     char* s3="", char* s4=""); 
void error(char* s1, double d2, 
     char* s3="", char* s4=""); 

void message(char* m1, 
    char* m2="", char* m3="", char* m4=""); 
void message(char* m1, double m2, 
    char* m3="", char* m4=""); 
void message(char* m1, double m2, char* m3, double m4); 
void message(char* m1, double m2, char* m3, double m4, 
    char* m5, double m6, char* m7, double m8); 
void message(char* m1, double m2, double m3, double m4, double m5); 
void message(char* m1, double m2, double m3, double m4); 
void message(char* m1, double m2, char* m3, double m4, char* m5, double m6); 
void message(char *s1, double d2, double d3); 
void message(char *s1, char *s2, double d3); 

void debug(char* m1, 
     char* m2="", char* m3="", char* m4=""); 
void debug(char* m1, double m2, 
     char* m3="", char* m4=""); 
void debug(char* m1 , double m2, char* m3, double m4); 
void debug(char* m1 , double m2, char* m3, double m4, char* m5, double m6); 
}; 

#endif 

はあなたを持っていますが、今私は、このエラーメッセージが表示されましたどのように私はそれを修正することができる任意のアイデア?はいの場合は、明確に書き留めてください(私は初心者です...)。 ありがとうございました!

void message(char* m1, 
    char* m2="", char* m3="", char* m4=""); 

問題がchar*秒として扱うことができるC++でその文字列リテラルですが、そうするのは非常に危険なのです:

+6

ではない...再び尋ねる前に検索を使用してください!ヒント: 'char * s2 =" "'は何が間違っているのですか – Xeo

答えて

24

は、私はあなたの警告は、このコードから来ていると思います。文字列リテラルで定義された配列に書き込むと、Undefined Behavior(セキュリティホール、プログラムクラッシュなどの原因となるもの)が発生しますが、通常の 'char*ポインタを使用すると、このような書き込みを行うことができます。このため、強くであり、char*をCスタイルの文字列を指すのではなく、const char*とすることをお勧めします。これにより、コンパイラが書き込みを試みていないことを確認できるようになります。あなたがC++を使用しているので、この場合は、あなたのコードはより良い

void message(char* m1, 
    const char* m2="", const char* m3="", const char* m4=""); 

のように書かれることになるしかし、ずっと良いアイデアは、ちょうどstd::stringを使用することです:

void message(std::string m1, 
    std::string m2="", std::string m3="", std::string m4=""); 

これは完全に回避しますなぜなら、C++ std::string型の引数にはconst char*が正しくあり、その文字列のディープコピーが作成されているからです。文字列を変更しようとすると元の文字配列を切り捨てることはありません。

希望すると便利です。

+0

...確かにそうです! +1 – Ben

-3

はヘッダに

#include <iostream> 

を試してみてください。

+0

明らかに人々は最高の答えを投票するために投稿を読んでいない。 – Borzh

6

あなたは、いくつかのオプションがあります。その文字列リテラル(例えば"foo")が暗黙char*に変換されることはありません飽きないよう

  • はあなたのコードを修正します。それらはconst char*である必要があります。

  • -Wno-write-stringsを含むようにコンパイラのコマンドラインを変更してください。これは、エラーメッセージの-Wwrite-stringsの部分が示唆しているものです。

私は最初のオプションを好むでしょう。

2

cerrが定義されていないというコンパイルエラーがあります。他の答えは、警告メッセージによって強調された問題を解決する方法を教えてくれます。コンパイルするには、iostreamをインクルードし、名前空間stdを使用する必要があります(または、ストリーム名とendlの前に名前空間を追加してください)。

はここにいくつかのサンプルコードです:

#include <iostream> 

using namespace std; 

int main() 
{ 
    cerr << "test" << endl; 
} 
関連する問題