13

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!

Community
  • 1
  • 1
user1013619
  • 149
  • 1
  • 1
  • 3
  • 6
    Not again... Please use the search before asking!! Hint: `char* s2 = ""` is what's wrong – Xeo Oct 25 '11 at 22:29

4 Answers4

24

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!

Florian Richoux
  • 1,543
  • 1
  • 14
  • 28
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
6

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.

asveikau
  • 39,039
  • 2
  • 53
  • 68
2

There's an compilation error, which states that cerr is not defined. Other answers tell You how to fix problems higlighted by warning messages. To compile you need to include iostream and use the namespace std (or add namespace before stream name and endl).

Here's some example code:

#include <iostream>

using namespace std;

int main( ) 
{
   cerr << "test" << endl;
}
baderman
  • 126
  • 3
  • 10
-3

Try

#include <iostream> 

in the header.

mday299
  • 129
  • 1
  • 6