分类: C/C++
2010-11-18 16:36:03
今天碰到了这个警告,老老实实的google了一下,以下是收获:
问题是这样产生的,先看这个函数原型:
void someFunc(char *someStr);
再看这个函数调用:
someFunc("I'm a string!");
把这两个东西组合起来,用最新的g++编译一下就会得到标题中的警告。
为什么呢?原来char *背后的含义是:给我个字符串,我要修改它。
而理论上,我们传给函数的字面常量是没法被修改的。
所以说,比较和理的办法是把参数类型修改为const char *。
这个类型说背后的含义是:给我个字符串,我只要读取它。
很自然的延伸一下。 如果我既要传字面常量又要传字符串变量怎么办呢?......重载
对deprecated conversion from string constant to 'char
*'此类警告的详细解释 假定你想使用一个char*类型的变量,有时指向一个字符串,有时指向另外一个字符串。开始的代码就像这样: char *msg; msg = "hello"; msg = "good-bye"; 编译器会对这段代码给出两段警示,说”deprecated conversion from string constant to 'char *'",意思就是说你没有能力修改字符串的内容。如果将代码写成这样,如: char *msg = "hello"; *msg = 'j'; printf( "%s\n", "hello" ); 编译器会通过编译,实际上会将msg指向的内容从"hello"转变为"jello", 正确的解决方法是将jmsg声明为一个指向不变字符串的指针: const char *msg; msg = "hello"; msg = "good-bye"; 这段代码可以成功编译,并且将msg指向的值如愿改变,但如果你将指针指向的指进行赋值: *msg = 'j'; 将会产生一个错误,不能修改一个字符串常量 注意如下的代码,此代码编译时不会出现警告也不会出现任何错误: const char *msg; char buf[ 10 ]; sprintf( buf, "%03d\n", 7 ); msg = buf; 改变buf的内容是可以的,因为它并没有被声明为常量。在这种情况下,msg将指向一个字符串,"007\n". 像这种语句 *buf = 'x'; 将会正确编译执行,但像 *msg = 'x'; 将会产生一个警告,因为msg指向的内容不允许改变 还有一种方法是使用强制转换,使用强制转换意味着你清楚会出现什么情况,不需要编译器为你做出判断,例如下面的代码将不会产生警告: char *msg; msg = (char *) "hello"; 但一旦你使用强制转换,编译器对如下语句进行编译时,也不会出现错误或警告 *msg = 'j'; 这个错误将一直存在,但并不会被发现,直到运行时。那时再找出错点就相当麻烦了,比编译器提醒你,麻烦多了。所以,最好不要对字符串使用强制转换。 Constant 指针 根据constant的位置不同,可以有以下四种情况: const char* const msg_0; const char *msg_1; char* const msg_2; char *msg_3; 其中,msg_0是一个constant指针指向一个const字符串。这个声明编译器会给出一个警告,因为msg_0的指向没有被初始化,而且之后的语句也无法对mg_0进行赋值,如 const char const *msg_0 = "hello"; 会编译成功,但 *msg_0 = 'j';或者 msg_0 = "good-bye"; 将会产生错误 msg_1既可以指向一个const字符串,也可以指向一个可变的字符串,但是不能修改它所指向的字符串的内容。 编译msg_2这条语句,会出现和编译msg_0一样的错误。因为指针是一个常量,所以它应该首先被赋值。如果刚开始已经赋值,那么它可以对指向的字符串内容进行修改,如: char buf[ 10 ]; char const *msg_2 = buf; 这段代码里,msg_2指向buf[0],并且永远指向这个地址,不会改变; 对于msg_3,就没太多可以说的。你可以改变指针,也可以改变指针指向的内容; |
参考文献:
http://blog.csdn.net/Chenah/archive/2010/01/01/5118458.aspx
http://hi.baidu.com/pjyang2010/blog/item/8db62eccc6deb433f8dc61d2.html