如何摆脱从GCCstring常量到'char *'警告的弃用转换?

所以我在一个非常大的代码库上工作,最近升级到gcc 4.3,现在触发这个警告:

警告:不推荐将string常量转换为“char *”

显然,解决这个问题的正确方法是find每个声明

char *s = "constant string"; 

或函数调用如:

 void foo(char *s); foo("constant string"); 

并使他们const char指针。 但是,这意味着至less要触及564个文件,这不是我希望在这个时候执行的任务。 现在的问题是,我正在运行-werror ,所以我需要一些方法来扼杀这些警告。 我怎样才能做到这一点?

我相信通过-Wno-write-strings来gcc会压制这个警告。

你传递string文字的任何函数"I am a string literal"应该使用char const *作为types而不是char*

如果你要解决一些问题,请修复它。

例:

 #include<iostream> using namespace std; void print(char *); void print(const char *ch) { cout<<ch; } int main(){ print("Hello"); return 0; } 

查看gcc的Diagnostic Pragma支持,以及-W警告选项列表(已更改: 指向警告选项的新链接 )。

对于gcc,您可以使用#pragma warning指令,如此处所述。

我有类似的问题,我解决这个问题:

 #include <string.h> extern void foo(char* m); int main() { // warning: deprecated conversion from string constant to 'char*' //foo("Hello"); // no more warning char msg[] = "Hello"; foo(msg); } 

这是解决这个问题的适当方法吗? 我没有访问foo来使它适应接受const char* ,尽pipe这将是一个更好的解决scheme(因为foo不会改变m )。

如果它是一个活跃的代码库,您可能仍然想要升级代码库。 当然,手动执行更改是不可行的,但我相信这个问题可以通过一个单一的sed命令来一劳永逸地解决。 我还没有尝试过,所以拿一点盐做下面的事。

 find . -exec sed -E -i .backup -n \ -e 's/char\s*\*\s*(\w+)\s*= "/char const* \1 = "/g' {} \; 

这可能无法find所有的地方(甚至不考虑函数调用),但它可以缓解问题,并可以手动执行less量的其他更改。

这里是如何在文件中内联它,所以你不必修改你的Makefile。

 // gets rid of annoying "deprecated conversion from string constant blah blah" warning #pragma GCC diagnostic ignored "-Wwrite-strings" 

你以后可以…

 #pragma GCC diagnostic pop 

我不能使用编译器开关。 所以我已经把这个变成了:

 char *setf = tigetstr("setf"); 

对此:

 char *setf = tigetstr((char *)"setf"); 

更换

 char *str = "hello"; 

 char *str = (char*)"hello"; 

或者如果您正在调用function:

 foo("hello"); 

用这个replace

 foo((char*) "hello"); 

代替:

 void foo(char *s); foo("constant string"); 

这工作:

 void foo(const char s[]); foo("constant string"); 

在C ++中,像下面这样使用const_cast

 char* str = const_cast<char*>("Test string"); 

Test string是常量string。 所以你可以这样解决:

 char str[] = "Test string"; 

要么:

 const char* str = "Test string"; printf(str); 

为什么不只是使用types铸造?

 (char*) "test" 

从常量stringtypes转换为字符指针即

 char *s = (char *) "constant string"; 

你也可以通过调用strdup()从一个string常量创build一个可写的string。

例如,这段代码会产生一个警告:

 putenv("DEBUG=1"); 

但是,下面的代码不会(在将它传递给putenv之前,它会将堆中的string复制一份):

 putenv(strdup("DEBUG=1")); 

在这种情况下(也许在大多数情况下)closures警告是一个坏主意 – 这是有原因的。 另一种select(使所有string默认可写)可能是低效的。

听听编译器告诉你什么!

看到这种情况:

 typedef struct tagPyTypeObject { PyObject_HEAD; char *name; PrintFun print; AddFun add; HashFun hash; } PyTypeObject; PyTypeObject PyDict_Type= { PyObject_HEAD_INIT(&PyType_Type), "dict", dict_print, 0, 0 }; 

看名字字段,在海湾合作委员会编译没有警告,但在G + +它会,我不知道为什么。

为什么不使用-Wno-deprecated选项来忽略弃用的警告消息?

只需使用-w选项为g ++

例:

g ++ -w -o simple.o simple.cpp -lpthread

请记住,这不会避免弃用,而是防止在terminal上显示警告消息。

现在,如果你真的想避免使用const关键字,像这样:

 const char* s="constant string"; 

BlackShift的答案是非常有用的,我用它:

 extern string execute(char* cmd) { FILE* pipe = popen(cmd, "r"); if (!pipe) return "ERROR"; char buffer[256]; std::string result = " "; while(!feof(pipe)) { if(fgets(buffer, 128, pipe) != NULL) result += buffer; } pclose(pipe); return result; } int main(){ char cmd[]="grep -A1 'xml' out1.txt | grep read|awk -F'=' 'BEGIN{sum=0}{sum=sum+$NF}END{print sum}'"; string result=execute(cmd); int numOfBytes= atoi(result.c_str()); cout<<"Number of bytes = "<<numOfBytes<<endl; return 0; } 

现在的问题是,我正在运行 – 错误

这是你真正的问题,国际海事组织。 你可以尝试从(char *)移动到(const char *)的一些自动化的方法,但我会把钱放在他们身上,而不仅仅是工作。 至less在一些工作中,你必须要有一个人参与。 短期内,只要忽略这个警告(但国际海事组织把它留下,否则它将永远不会被修复),只要删除 – 错误。

谢谢,所有的帮助。 从这里和那里采摘这个解决scheme。 这编译干净。 尚未testing代码。 明天…也许…

 const char * timeServer[] = { "pool.ntp.org" }; // 0 - Worldwide #define WHICH_NTP 0 // Which NTP server name to use. ... sendNTPpacket(const_cast<char*>(timeServer[WHICH_NTP])); // send an NTP packet to a server ... void sendNTPpacket(char* address) { code } 

我知道,timeServer数组中只有一个项目。 但可能会有更多。 其余的被评论出来,目的是为了节省内存。

 PyTypeObject PyDict_Type= { ... PyTypeObject PyDict_Type= { PyObject_HEAD_INIT(&PyType_Type), "dict", dict_print, 0, 0 }; 

看名字字段,在海湾合作委员会编译没有警告,但在G + +它会,我不知道为什么。

gcc (Compiling C) ,-Wno-write-strings默认是激活的。

g++ (Compiling C++) Wwrite-strings默认是激活的

这就是为什么有不同的行为。 对于我们使用Boost_pythonmacrosBoost_python产生这样的警告。 所以我们在编译C ++时使用-Wno-write-strings ,因为我们总是使用-Werror