2011-10-25 10 views
13

Powiel możliwe:
Deprecated conversion from string constant to char * errorC++ - przestarzałe konwersji z ciągiem stałym do 'char *'

Próbowałem uruchomić starego kodu C++ dzisiaj (kod ten poszedł w prawo w 2004 roku :) . Ale teraz mam ten komunikat o błędzie:

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 

Źródło "error.C" file:

... 
#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); 
} 
... 

i źródło "error.h" file:

... 
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 

masz jakiś pomysł, jak to naprawić? Jeśli tak, proszę napisać to wyraźnie (jestem nowicjuszem ...). Dziękujemy!

+6

Nie znowu ... Proszę szukać przed pytaniem !! Podpowiedź: 'char * s2 =" "' jest co jest nie tak – Xeo

Odpowiedz

24

myślę, że ostrzeżenia są pochodzące z tego kodu:

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

Problem jest, że literały ciągów znaków w C++ mogą być traktowane jako char* s, ale jest to bardzo niebezpieczne, aby to zrobić. Zapisywanie do tablicy zdefiniowanej przez literał łańcuchowy powoduje niezdefiniowane zachowanie (coś, co powoduje luki w zabezpieczeniach, awarie programu, itp.), Ale regularny wskaźnik "char* pozwoliłby na wykonanie tego rodzaju zapisu. Z tego powodu jest zdecydowanie zasugerował, aby wszystkie char* s, które wskazywałyby na ciąg w stylu C zamiast być const char* s, tak aby kompilator mógł sprawdzić, aby upewnić się, że nie próbujesz do nich pisać. W tym przypadku kod będzie lepiej napisane jak

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

Jednakże, ponieważ używasz C++, A znacznie lepszym pomysłem jest po prostu użyć std::string:

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

Ten całkowicie unika problem, ponieważ typ C++ std::string ma w swoich argumentach odpowiednio const char* s i tworzy głęboką kopię napisu, więc jeśli spróbujesz zmutować ciąg znaków, masz gwarancję, że nie zniszczysz oryginalnej tablicy znaków.

Mam nadzieję, że to pomoże!

+0

... to na pewno robi! +1 – Ben

-3

Spróbuj

#include <iostream> 

w nagłówku.

+0

Oczywiście ludzie nie czytają tego postu, aby głosować najlepszą odpowiedzią. – Borzh

6

Masz kilka opcji:

  • naprawić swój kod tak, że literały łańcuchowe nigdy się niejawnie konwertowane do char* (np "foo".). Powinny one być const char*.

  • Zmień wiersz komend kompilatora na -Wno-write-strings. Właśnie to sugeruje część komunikatu o błędzie -Wwrite-strings.

Wolałbym pierwszą opcję.

2

Występuje błąd kompilacji, który stwierdza, że ​​cerr nie jest zdefiniowany. Inne odpowiedzi podpowiedzą Ci, jak rozwiązać problemy, które są wyróżniane przez komunikaty ostrzegawcze. Aby skompilować, musisz dołączyć iostream i użyć przestrzeni nazw std (lub dodać przestrzeń nazw przed nazwą strumienia i endl).

Oto niektóre przykładowy kod:

#include <iostream> 

using namespace std; 

int main() 
{ 
    cerr << "test" << endl; 
}