C&C++ String Literal对char*="stringLiteral"的弃用;

use*_*167 0 c c++

我理解语法char*="stringLiteral"; 已被弃用,未来甚至可能无法使用.我不明白的是为什么.

我搜索网和堆栈,虽然有许多回声确认char*="stringLiteral"; 是错的,那个const char*="stringLiteral"; 是核心,我还没有找到有关WHY表示语法错误的信息.换句话说,我想知道问题究竟是什么.

我的困惑

CODE SEGMENT 1 - EVIL WAY(已弃用)

char* szA = "stringLiteralA";     //Works fine as expected. Auto null terminated.
std::cout << szA << std::endl;    
szA = "stringLiteralB";          //Works, so change by something same length OK.
std::cout << szA << std::endl;    
szA = "stringLiteralC_blahblah"; //Works, so change by something longer OK also.
std::cout << szA << std::endl;    

Ouput:
stringLiteralA
stringLiteralB
stringLiteralC_blahblah
Run Code Online (Sandbox Code Playgroud)

那究竟是什么问题呢?似乎工作得很好.

CODE SEGMENT 2("OK"方式)

const char* szA = "stringLiteralA";  //Works fine as expected. Auto null term.
std::cout << szA << std::endl;    
szA = "stringLiteralB";          //Works, so change by something same length OK.
std::cout << szA << std::endl;    
szA = "stringLiteralC_blahblah"; //Works, so change by something longer OK also.
std::cout << szA << std::endl;    

Ouput:
stringLiteralA
stringLiteralB
stringLiteralC_blahblah
Run Code Online (Sandbox Code Playgroud)

也工作正常.没有不同.添加const有什么意义?

代码段3

const char* const szA = "stringLiteralA";  //Works. Auto null term.
std::cout << szA << std::endl;    
szA = "stringLiteralB";           //Breaks here. Can't reasign.
Run Code Online (Sandbox Code Playgroud)

我只是在这里说明为了只读保护变量内容你必须使用const char*const szA ="something"; .

我没有看到弃用或任何问题.为什么弃用此语法并将其视为问题?

Mat*_*lia 6

const char *是一个指向*常量(const)的char指针()(指针定义很容易从右到左阅读).这里的要点是保护内容,因为正如标准所说,修改这种指针的内容会导致不确定的行为.

这源于这样一个事实:通常(C/C++)编译器将整个程序中使用的字符串分组到单个内存区域中,并且允许对程序的不相关部分中使用的相同字符串的实例使用相同的内存位置. (以最小化可执行文件大小/内存占用).如果允许修改字符串文字,则可能会影响另一个更改其他相同文字的无关实例,这显然不是一个好主意.

事实上,对于大多数现代编译器(在支持内存保护的硬件上),字符串表的内存区域是只读的,因此如果您尝试修改字符串文字,程序将崩溃.添加const到引用字符串文字的指针会使这些错误立即显现为编译错误而不是崩溃.

顺便说一下,请注意字符串文字可以隐式地衰减到非const的事实char *只是向前兼容预标准库(当const不是C语言的一部分时编写)的让步,如上所述标准总是说改变字符串文字是UB.