当前位置:  开发笔记 > 编程语言 > 正文

如何摆脱GCC中从字符串常量到'char*''警告的弃用转换?

如何解决《如何摆脱GCC中从字符串常量到'char*''警告的弃用转换?》经验,为你挑选了11个好方法。

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

警告:不推荐将字符串常量转换为'char*'

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

char *s = "constant string";

或函数调用如:

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

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



1> John..:

传递字符串文字的任何函数"I am a string literal"都应该char const *用作类型而不是char*.

如果你要解决问题,请正确解决问题.

说明:

您不能使用字符串文字初始化将要修改的字符串,因为它们是类型const char*.虚掷常量性以后修改它们是不确定的行为,所以你要复制你的const char*字符串char通过char到动态分配的char*字符串,以对其进行修改.

例:

#include 

void 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..:

我遇到了类似的问题,我解决了这个问题:

#include 

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*,虽然这将是一个更好的解决方案(因为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);

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有