C ++ - 从字符串常量到'char *'的不推荐转换[重复]

Posted

技术标签:

【中文标题】C ++ - 从字符串常量到\'char *\'的不推荐转换[重复]【英文标题】:C++ - deprecated conversion from string constant to ‘char*’ [duplicate]C ++ - 从字符串常量到'char *'的不推荐转换[重复] 【发布时间】:2011-10-25 22:27:52 【问题描述】:

可能重复:Deprecated conversion from string constant to 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

您知道我该如何解决吗?如果是,请写清楚(我是新手……)。 谢谢!

【问题讨论】:

不再...请在询问之前使用搜索!提示:char* s2 = "" 出了什么问题 【参考方案1】:

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

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

问题是 C++ 中的字符串文字可以被视为char*s,但这样做非常不安全。写入由字符串字面量定义的数组会导致未定义的行为(导致安全漏洞、程序崩溃等的事情),但常规的 ol'char* 指针将允许您执行此类写入。出于这个原因,强烈建议您将所有指向 C 样式字符串的 char*s 改为 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 并制作了字符串的深层副本,因此如果您尝试改变字符串,则可以保证您不会会破坏原来的字符数组。

希望这会有所帮助!

【讨论】:

【参考方案2】:

你有几个选择:

修复您的代码,使字符串文字(例如"foo")永远不会被隐式转换为char*。他们应该是const char*

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

我更喜欢第一个选项。

【讨论】:

【参考方案3】:

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

下面是一些示例代码:

#include <iostream>

using namespace std;

int main( ) 

   cerr << "test" << endl;

【讨论】:

【参考方案4】:

试试

#include <iostream> 

在标题中。

【讨论】:

显然人们不会阅读帖子来投票否决最佳答案。

以上是关于C ++ - 从字符串常量到'char *'的不推荐转换[重复]的主要内容,如果未能解决你的问题,请参考以下文章

从字符串常量到 'char*' 的折旧转换

为啥从字符串常量转换为 'char*' 在 C 中有效但在 C++ 中无效

C++ 警告:不推荐使用从字符串常量到“char*”的转换 [-Wwrite-strings]

C语言如何实现两个非常量的CHAR字符串连接

深入Java源码剖析之字符串常量

C++ 不推荐将字符串常量转换为 'char*'