字符串字面量到'char*'的转换已被弃用

60

我的程序声明了一个字符串数组,就像这样:

char *colors[4] = {"red", "orange", "yellow", "blue"};

但是我得到了上面的编译器警告。虽然它可以编译,但如果有非弃用方法的话,我宁愿使用它。我尝试找出它的含义,但似乎无法弄清楚。我听说在'char'之前使用'const'可以解决问题,但如果有人能解释一下错误的含义会很有帮助。谢谢。

3个回答

81
你输入的字符串:"red","orange"等是“文字量”,因为它们是在程序代码内部定义的(它们不会直接从磁盘、用户输入/stdin等读取)。
这意味着,如果你尝试在任何时候写入你的“colors”,你将直接访问原始输入并因此编辑它。这将导致一些不希望发生的运行时错误。
将其声明为常量将确保您永远不会尝试写入该指针,从而可以避免此类运行时错误。
const char *colors[4] = {"red", "orange", "yellow", "blue"};

如果您曾经想在运行时编辑这些值,那么您应该先复制这些字符串。


5
需要的类型签名应该是 char const *colors[4],我的理解是一个由四个常量指针组成的数组。 - James Aylett
1
@JamesAylett,不是const char colors[4],而是const char *colors[4]。这是一个指向常量数据的4个指针数组。 - HolyBlackCat
2
@HolyBlackCat:这不是一样的吗? - szx
1
@szx,我认为他拼错了:an array of four constant pointers应该是char * const colors[4]char const *colors[4]是一种奇怪但有效的描述四个指向常量数据的指针数组的方式。 - HolyBlackCat
3
“const pointer to data” 不同于 “pointer to const data”。前者是指一个指针本身不能被改变,但它所指向的数据可以被修改;后者则是指一个指针本身可以被改变,但其所指向的数据为常量,不可被修改。更多讨论请参见 codeguru。(是的,我知道我有些晚了,但这是一个经常混淆的问题)。 - JRobert

11
"red", "orange", "yellow", "blue"

这些是常量字符串。创建一个非const指向常量字符串的指针是错误的,因此会产生警告。目前您收到了一条警告,但它应该是一个错误,因为在C++03中已弃用,在C++11中被禁止使用。


6

这些答案都是正确的。

请注意,如果您有一个需要作为参数的字符数组的函数,并且您像这样传递此参数:

foo ("bar");

相同的警告信息将被显示。在这种情况下,您可以选择以下方法之一:
1)按照第一个答案中所述更改它:
void foo (char[] str) { printf(str); }

const char param[] = "bar";
foo (param);

2) 考虑使用C++标准字符串,如下所示:

void foo (std::string theParam) { std::cout << theParam; }

foo ("bar");

IMHO,只要没有真正的性能问题并且您不使用C库,或者如果您正在构建供他人使用的C++库,则应该使用C++不可变字符串及其功能集。如果Unicode是必需的,则C++中的支持“很糟糕”,如此处所述。 这个问题会给您一些提示(主要是:使用IBM ICU库)。如果您的项目已经使用Qt,QString也可以胜任,Gettext也是如此。

1
函数声明 void foo (char[] str) { printf(str); } 缺少 const,应该是 void foo (const char[] str) { printf(str); }。前者会抛出一个 candidate function not viable: 1st argument ('const char *') would lose const qualifier 错误。 - Aldo Utrera
我尝试了这两种方法。编译器警告:从 'const char*' 到 'char*' 的转换无效 - Codes with Hammer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接