所以我正在开发一个非常大的代码库,最近升级到gcc 4.3,它现在触发了这个警告:
警告:不推荐将字符串常量转换为'char*'
显然,解决这个问题的正确方法是找到每个声明
char *s = "constant string";
或函数调用如:
void foo(char *s); foo("constant string");
并使他们成为const char
指针.但是,这意味着触及564个文件,最小,这不是我希望在此时执行的任务.现在的问题是我正在运行-werror
,所以我需要一些方法来扼杀这些警告.我怎样才能做到这一点?
传递字符串文字的任何函数"I am a string literal"
都应该char const *
用作类型而不是char*
.
如果你要解决问题,请正确解决问题.
说明:
您不能使用字符串文字初始化将要修改的字符串,因为它们是类型const char*
.虚掷常量性以后修改它们是不确定的行为,所以你要复制你的const char*
字符串char
通过char
到动态分配的char*
字符串,以对其进行修改.
例:
#includevoid print(char* ch); void print(const char* ch) { std::cout<
虽然这是真的,但你并不总能控制第三方API,它们可能无法正确使用`char*`/`const char*`,所以在这种情况下我通常会施放.
@ppumkin不幸的是,许多C标准库字符串函数将参数作为`char*`,即使对于不会被修改的字符串也是如此.如果你把一个参数作为`char const*'并将它传递给一个带有`char*`的标准函数,那你就可以点击它.如果库函数不会操作字符串,你可以抛弃`const`.
2> DGentry..:我相信传递
-Wno-write-strings
给gcc会压制这个警告.
这是令人难以置信的糟糕做法,我很遗憾它得到了所有这些选票.没有警告,所以你忽略它们.警告告诉你"伙计,你做的事情可能是错的,要小心",你应该只在你想回应时压抑它们,比如"闭嘴,我知道我在做什么",这很可能不是婴儿程序员的情况.
@PriyankBolia bdonlan评论了Rob Walker的答案,它可以使用`#pragma GCC diagnostic ignored"-Wwrite-strings"`.
除非您控制API,在这种情况下@ John的答案,关于更改签名以接受const char*,更为正确.
我同意,你不应该摆脱警告,而是使用约翰提供的解决方案.太糟糕了这个是接受的答案!
是否可以使用pragma在每个文件基础上禁用它.
3> Rob Walker..:查看gcc的Diagnostic Pragma支持,以及-W警告选项列表(已更改:警告选项的新链接).
对于gcc,您可以使用此处
#pragma warning
说明的指令.
实际上它确实:#pragma GCC诊断忽略了"-Wwrite-strings"
4> BlackShift..:我遇到了类似的问题,我解决了这个问题:
#includeextern 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*
,虽然这将是一个更好的解决方案(因为foo
不会改变m
).
@elcuco,你会建议什么?我无法编辑foo,并试图找到一个不需要抑制警告的解决方案.就我而言,后者更多的是运动问题,但对于原始海报来说,它似乎很重要.据我所知,我的答案是唯一能够同时解决我和OP条件的答案,因此它可能是对某人有价值的答案.如果您认为我的解决方案不够好,请您提供替代方案吗?(这不包括编辑foo或忽略警告.)
5> Konrad Rudol..:如果它是活动代码库,您可能仍希望升级代码库.当然,手动执行更改是不可行的,但我相信这个问题可以通过一个
sed
命令一劳永逸地解决.但是,我没有尝试过,所以请注意以下几点.find . -exec sed -E -i .backup -n \ -e 's/char\s*\*\s*(\w+)\s*= "/char const* \1 = "/g' {} \;这可能找不到所有位置(甚至不考虑函数调用),但它可以缓解问题并使手动执行少量剩余更改成为可能.
这只能解决声明警告而不是函数调用+1 for sed fu:p
6> vy32..:我不能使用编译器开关.所以我转过身来:
char *setf = tigetstr("setf");对此:
char *setf = tigetstr((char *)"setf");
当我这样做时,我得到"警告:从类型'const char*'强制转换为'char*'强制转换为constness".我不得不使用const_cast来消除所有警告:const_cast("setf")
我认为const cast是此页面上第一个可接受的解决方案(API更改除外).
7> EdH..:以下是如何在文件中内联,因此您不必修改Makefile.
// gets rid of annoying "deprecated conversion from string constant blah blah" warning #pragma GCC diagnostic ignored "-Wwrite-strings"你可以稍后......
#pragma GCC diagnostic pop
8> 小智..:更换
char *str = "hello";同
char *str = (char*)"hello";或者如果你在函数中调用:
foo("hello");用它代替
foo((char*) "hello");
9> 小智..:代替:
void foo(char *s); foo("constant string");这有效:
void foo(const char s[]); foo("constant string");
10> appapurapu..:在C++中,使用
const_cast
如下所示char* str = const_cast("Test string");
11> 小智..:
Test string
是const字符串.所以你可以这样解决:char str[] = "Test string";要么:
const char* str = "Test string"; printf(str);