C++ - устаревшее преобразование из строковой константы в 'char*'

Возможный дубликат:
Устаревшее преобразование из строковой константы в char * error

Я пытался запустить старый код C++ сегодня (этот код был исправлен в 2004 году:). Но теперь я получил это сообщение об ошибке:

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

Источник файла "error.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":

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

Ты хоть представляешь, как я могу это исправить? Если да, пожалуйста, запишите это ясно (я новичок...). Спасибо!

4 ответа

Я думаю, что ваши предупреждения приходят из этого кода:

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

Проблема в том, что строковые литералы в C++ могут рассматриваться как char*с, но это очень небезопасно. Запись в массив, определенный строковым литералом, приводит к неопределенному поведению (то, что вызывает дыры в безопасности, сбоям программы и т. Д.), Но обычному char* Указатель позволит вам сделать такую ​​запись. По этой причине настоятельно рекомендуется сделать все char*s, которые будут указывать на строку в стиле C вместо const char*s, чтобы компилятор мог проверить, чтобы убедиться, что вы не пытаетесь писать в них. В этом случае ваш код будет лучше написан как

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

Однако, так как вы используете C++, гораздо лучше использовать std::string:

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

Это полностью исключает проблему, потому что C++ std::string тип правильно имеет const char*s в своих аргументах и ​​делает глубокую копию строки, поэтому, если вы попытаетесь изменить строку, это гарантирует, что вы не собираетесь уничтожать исходный массив символов.

Надеюсь это поможет!

У вас есть несколько вариантов:

  • Исправьте ваш код так, чтобы строковые литералы (например, "foo"никогда не преобразуется в char*, Они должны быть const char*,

  • Измените командную строку вашего компилятора, чтобы включить -Wno-write-strings, Это то, что -Wwrite-strings часть сообщения об ошибке намекает на.

Я бы предпочел первый вариант.

Есть ошибка компиляции, которая утверждает, что cerr не определен. Другие ответы говорят вам, как исправить проблемы, выделенные предупреждающими сообщениями. Для компиляции вам нужно включить iostream и использовать пространство имен std (или добавить пространство имен перед именем потока и endl).

Вот пример кода:

#include <iostream>

using namespace std;

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

Пытаться

#include <iostream> 

в шапке.

Другие вопросы по тегам