如何摆脱从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_python
macrosBoost_python
产生这样的警告。 所以我们在编译C ++时使用-Wno-write-strings
,因为我们总是使用-Werror