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

我正在处理一个非常大的代码库,最近升级到GCC 4.3,现在触发了这个警告:

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

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

char *s = "constant string";

或者像这样调用函数:

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

并使它们成为const char指针。但是,这意味着至少要接触564个文件,这不是我目前希望执行的任务。现在的问题是我正在运行-Werror,所以我需要一些方法来抑制这些警告。我该怎么做呢?

453035 次浏览

我相信将-Wno-write-strings传递给GCC将抑制此警告。

查看GCC的诊断编译指示支持,以及-W警告选项. xml的列表。

对于GCC,你可以使用#pragma warning指令,比如解释过的在这里

如果它是一个活动的代码库,您可能仍然希望升级代码库。当然,手动执行更改是不可行的,但我相信这个问题可以通过一个sed命令一劳永逸地解决。不过,我还没有尝试过,所以对下面的建议半信半疑。

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

这可能无法找到所有的位置(甚至不考虑函数调用),但它可以缓解问题,并使手动执行剩余的更改成为可能。

现在的问题是我用的是-Werror

在我看来,这才是你真正的问题。你可以尝试一些自动的方法从(char *)移动到(const char *),但我打赌他们不仅仅是工作。你将不得不让一个人参与至少一些工作。 在短期内,忽略警告(但在我看来,它是开着的,否则它永远不会得到修复),只需删除-Werror.

使用-Wno-deprecated选项可以忽略已弃用的警告消息。

我也遇到过类似的问题,我是这样解决的:

#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*,这将是一个更好的解决方案,因为foo没有改变m

你也可以通过调用strdup()从字符串常量创建一个可写的字符串。

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

putenv("DEBUG=1");

然而,下面的代码没有这样做(它在将字符串传递给putenv之前在堆上复制了一个字符串):

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

在这种情况下(也许在大多数情况下)关闭警告是一个坏主意——它的存在是有原因的。另一种替代方法(默认情况下使所有字符串都可写)可能效率很低。

听听编译器在告诉你什么!

我不能使用编译器开关。所以我把这个:

char *setf = tigetstr("setf");

:

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

Test string是const字符串。所以你可以这样求解:

char str[] = "Test string";

或者:

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

看看这个情况:

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
};

注意的名字字段。使用gcc时,它编译时没有警告,但在g++中会。我不知道为什么。

只使用类型转换:

(char*) "test"

下面是如何在文件中内联完成它,因此您不必修改Makefile。

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

之后你可以…

#pragma GCC diagnostic pop

再保险shindow的“answer":

PyTypeObject PyDict_Type=
{
...


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

注意的名字字段。使用gcc时,它编译时没有警告,但在g++中会。我不知道为什么。

gcc(编译C语言)中,-Wno-write-strings默认是活动的。

g++(编译c++)中,-Wwrite-strings默认是活动的

这就是为什么会有不同的行为。

对于我们来说,使用Boost_python的宏会产生这样的警告。 所以我们在编译c++时使用-Wno-write-strings,因为我们总是使用-Werror.

只要为g++使用- w选项即可。

例子:

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

记住,这并不能避免弃用。相反,它阻止在终端上显示警告信息。

现在,如果你真的想避免弃用,可以像这样使用常量关键字:

const char* s = "constant string";

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

如果你要修理什么东西,就把它修好。

解释:

你不能使用字符串字面量来初始化将要修改的字符串,因为它们的类型是const char*。放弃constness以稍后修改它们的方法是未定义的行为,因此你必须将你的const char*字符串char by char复制到动态分配的char*字符串中才能修改它们。

例子:

#include <iostream>


void print(char* ch);


void print(const char* ch) {
std::cout<<ch;
}


int main() {
print("Hello");
return 0;
}

从常量字符串到字符指针进行类型转换。

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

而不是:

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");

取代

char *str = "hello";

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

或者如果你在调用函数:

foo("hello");

将其替换为

foo((char*) "hello");

从这里到那里,就得到了这个解。这编译干净。

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数组中只有一项。但可能还有更多。其余部分现在被注释掉以节省内存。

在c++中,替换:

char *str = "hello";

:

std::string str ("hello");

如果你想比较一下:

str.compare("HALLO");

我不明白如何应用你的解决方案:(- kalmanIsAGameChanger

使用Arduino 草图,我有一个函数引起了我的警告。

最初的功能:

char StrContains(char *str, char *sfind)

为了停止警告,我在char *str和char * find前面添加了常量

修改:

char StrContains(const char *str, const char *sfind).

所有的警告都消失了。

字符串常量传递给函数时,将其写成:

void setpart(const char name[]);


setpart("Hello");

除了const char name[],你也可以写const char \*name

它为我消除了这个错误:

[Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]