C++ - 已弃用从字符串常量到“char*”的转换

发布于 2024-12-12 02:27:07 字数 3822 浏览 0 评论 0原文

可能的重复:
已弃用从字符串常量到 char * 的转换错误

我尝试今天运行旧的 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

您知道如何修复它吗?如果是的话,请写清楚(我是新手……)。 谢谢你!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

灵芸 2024-12-19 02:27:07

我认为您的警告来自这段代码:

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

问题是 C++ 中的字符串文字可以被视为 char* ,但这样做非常不安全。写入由字符串文字定义的数组会导致未定义的行为(导致安全漏洞、程序崩溃等的事情),但常规的 ol' char* 指针将允许您执行以下操作这种写法。因此,强烈建议您将所有指向 C 样式字符串的 char* 改为 const char*以便编译器可以检查以确保您不会尝试写入它们。在这种情况下,您的代码最好写为

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* 并生成字符串的深层复制,因此如果您尝试进行变异该字符串保证你不是将会破坏原来的字符数组。

希望这有帮助!

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!

萌化 2024-12-19 02:27:07

您有几个选择:

  • 修复您的代码,以便字符串文字(例如“foo”)永远不会隐式转换为char*。它们应该是 const char*

  • 更改编译器命令行以包含 -Wno-write-strings。这就是错误消息的 -Wwrite-strings 部分所暗示的内容。

我更喜欢第一个选择。

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.

猫烠⑼条掵仅有一顆心 2024-12-19 02:27:07

存在编译错误,表明 cerr 未定义。其他答案告诉您如何解决警告消息突出显示的问题。要编译,您需要包含 iostream 并使用命名空间 std(或在流名称和 endl 之前添加命名空间)。

这是一些示例代码:

#include <iostream>

using namespace std;

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

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;
}
我还不会笑 2024-12-19 02:27:07

尝试

#include <iostream> 

在标题中。

Try

#include <iostream> 

in the header.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文