Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ - deprecated conversion from string constant to ‘char*’ [duplicate]

Possible Duplicate:
Deprecated conversion from string constant to char * error

I tried to run old C++ code today (this code gone right in 2004 :). But now I got this error message:

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

Source of "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);
}
...

And source of "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

Have you any idea how I could fix it? If yes, please write it down clearly (I am newbie...). Thank you!

like image 873
user1013619 Avatar asked Oct 25 '11 22:10

user1013619


2 Answers

I think that your warnings are coming from this code:

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

The issue is that string literals in C++ can be treated as char*s, but it's very unsafe to do so. Writing to an array defined by a string literal results in Undefined Behavior (the sort of thing that causes security holes, program crashes, etc.), but a regular ol' char* pointer would allow you to do this sort of write. For this reason, it is strongly suggested that you make all char*s that would point to a C-style string instead be const char*s so that the compiler can check to make sure that you aren't try to write to them. In this case, your code would be better written as

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

However, since you're using C++, a much better idea is just to use std::string:

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

This completely avoids the issue, because the C++ std::string type correctly has const char*s in its arguments and makes a deep-copy of the string, so if you try to mutate the string it's guaranteed that you're not going to be trashing the original array of characters.

Hope this helps!

like image 194
templatetypedef Avatar answered Oct 14 '22 04:10

templatetypedef


You have a few options:

  • Fix your code so that string literals (eg. "foo") never get implicitly converted to char*. They should be const char*.

  • Change your compiler command line to include -Wno-write-strings. This is what the -Wwrite-strings part of the error message is hinting at.

I would prefer the first option.

like image 25
asveikau Avatar answered Oct 14 '22 05:10

asveikau