为啥在一种情况下会收到带有字符串文字的不推荐使用的转换警告,而在另一种情况下却没有?

Posted

技术标签:

【中文标题】为啥在一种情况下会收到带有字符串文字的不推荐使用的转换警告,而在另一种情况下却没有?【英文标题】:Why do I get a deprecated conversion warning with string literals in one case but not another?为什么在一种情况下会收到带有字符串文字的不推荐使用的转换警告,而在另一种情况下却没有? 【发布时间】:2017-11-04 01:59:01 【问题描述】:

我正在学习 C++。在这里显示的程序中,据我所知,str1str2 存储每个相关字符串的第一个字符的地址:

#include <iostream>
using namespace std;

int main() 

    char str1[]="hello";
    char *str2="world";
    cout<<str1<<endl;
    cout<<str2<<endl;

但是,str1 没有给出任何警告,而 str2 我收到了这个警告:

warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     char *str2="world";

这两个声明在第二种情况下导致警告而不是第一种情况有什么不同?

【问题讨论】:

"str1 和 str2 存储字符串第一个字符的地址"。这不是真的。 str1 存储整个字符串本身的副本。它不存储任何“地址”。另一方面,str2 确实存储了地址。 HI ANT,如果一个副本存储在 str1 中,“hello”的另一个副本将存储在哪里?如果我们修改 str1 副本说 str[0]='H',这个更改会影响另一个副本吗? 原始"hello" 存储在静态且不可修改的内存中。当您执行str[0] = 'H' 时,您会修改存储在str1 中的副本。原件保持不变。 【参考方案1】:

当你写作时

char str1[] = "hello";

您是说“请给我一个包含字符串"hello"chars 数组,并请选择数组str1 的大小作为初始化它的字符串的大小。”这意味着str1 最终存储了它自己的字符串"hello" 的唯一副本。 str1 的最终类型是 char[6] - 五个用于hello,一个用于空终止符。

当你写作时

char *str2 = "world";

您是在说“请给我一个类型为 char * 的指针,它指向字符串文字 "world"。”字符串文字"world" 的类型为const char[6] - 它是一个由六个字符组成的数组(五个用于hello,一个用于空终止符),重要的是这些字符是const 并且不能被修改。由于您使用char * 指针指向该数组,因此您将丢失const 修饰符,这意味着您现在(不安全地)拥有指向const 数据位的非const 指针。

这里情况不同的原因是,在第一种情况下,您获得了字符串"hello"副本,因此您的数组不是const 的事实是'一个问题。在第二种情况下,您没有获得"hello" 的副本,而是获得了指向它的指针,并且由于您获得了指向它的指针,因此担心修改它可能是一个真正的问题。

换一种说法,在第一种情况下,您会得到一个由六个字符组成的诚实的数组,其中包含 hello 的副本,因此如果您决定去改变这些字符也没问题.在第二种情况下,您将获得一个指针,该指针指向您不应该修改的六个字符的数组,但您使用的指针允许您改变事物。

那么为什么"world"const char[6]?作为对许多系统的优化,编译器只会将"world" 的一个副本放入程序中,并使文字"world" 的所有副本指向内存中完全相同的字符串。这很好,只要您不更改该字符串的内容。 C++ 语言通过说这些字符是const 来强制执行这一点,因此对它们进行变异会导致未定义的行为。在某些系统上,这种未定义的行为会导致诸如“哇,我的字符串文字中的值错误!”之类的事情,而在其他系统中,它可能只是段错误。

【讨论】:

您好,这是一个很好的答案。我可以知道“hello”和“world”都被认为是字符串文字吗?或者只有“world”被认为是字符串文字(bcz它被分配给char *)? “hello”和“world”都是字符串文字。此处的差异取决于您将这些文字分配给的内容。在第一种情况下,赋值被视为数组初始化,因此制作了文字的副本。第二个是指针初始化,所以不做拷贝。【参考方案2】:

问题是您正在尝试将字符串文字(类型为 const char*)转换为 char*。

【讨论】:

虽然这是真的,但我认为它并没有解决 OP 关于为什么第一个选项不起作用的问题。

以上是关于为啥在一种情况下会收到带有字符串文字的不推荐使用的转换警告,而在另一种情况下却没有?的主要内容,如果未能解决你的问题,请参考以下文章

在Word里,设置成标题的文字,更改正文后它的段落格式也跟着变了,为啥?谢谢

为啥 Rust 不允许在一种类型上复制和删除特征?

excel在一列前加相同的文字为啥前一列的文字会被覆盖

为啥将字符串文字传递给 char* 参数有时只是编译器错误?

为啥在一种情况下更改熊猫数据框列中的值很快,而在另一种情况下更改速度很慢?

为啥文字不是 const (字符串除外)?