c/c++ 中的字符数组指针赋值

pointer-to-char-array assignments in c/c++

过去我一直在使用 Visual Studio 2010/2013/2015 并且这种语法是可能的:

char* szString = "This works!";

我决定开始并改变我的编码生活方式,向 Linux 迈进,因为我已经安装了 g++ 并将 SlickEdit 作为我的 IDE。

这句话好像不行了。 谁能说说为什么?

然而这有效:

char strString[] = "This works!";

错误与 c++11 有关。

有人知道为什么会这样吗?不是如何修复它,因为在我的工作区中没有任何方法可以安装 c++11 编译器,我只是好奇它是否与编译器工作原理的背景有关。 关于第一行代码,我所知道的是,它在堆栈上创建了一个常量变量,并创建了一个新的指针,将自身设置为指向该 ESP 的值,但在第二行中,它计算了常量变量上的字母数量,然后结果在最后设置一个空终止符。

哦还有一件事 -> GCC/GPP 中第一个的设置方式似乎也有所不同,因为第一个类型是 {char*&} 而第二个是 { char(*)[12]},对此也有任何解释吗?谢谢!

当您编写文字 "text" 时,该文本将包含在已编译程序映像的某处。出于安全原因,程序映像通常放在现代操作系统的写保护内存中。

char* someString = "text"; 声明了一个指向您可能写保护的程序映像中的字符串的指针。将此指针声明为非常量的能力是 C++11 之前包含的一项功能,以保持与 C 的源代码兼容性。请注意,即使 someString 不是指向常量的指针,任何修改该值的尝试它指向的仍然会导致未定义的行为。 C++11 中删除了此向后兼容性功能。 someString 现在必须声明为指向常量的指针:const char* someString = "text";。您可以放弃 const,但尝试写入指向的值仍然会导致未定义的行为,这与您强制转换为非常量的任何 const 值相同。

char someString[] = "text"; 的工作方式不同。这会将字符串 "text" 从程序的代码内存复制到位于数据内存中的数组中。它类似于

char someString[5];
strcpy(someString, "text");

因为someString是程序数据内存中的一个数组,所以可以写入它,而且不需要是const-qualified。

根据标准:Annex C(兼容性)

C1.1 子条款 2.14.5:

Change: String literals made const

The type of a string literal is changed from “array of char” to “array of const char.” The type of a char16_t string literal is changed from “array of some-integer-type” to “array of const char16_t.” The type of a char32_t string literal is changed from “array of some-integer-type” to “array of const char32_t.”

The type of a wide string literal is changed from “array of wchar_t” to “array of const wchar_t.”

Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument.

事实上,C++ 标准 2.14.5.8 说:

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration

这也允许这样的字符串得到各种特殊处理:compiler/linker可以选择跨编译单元消除字符串的重复项,(msvc术语中的字符串池),它可以将它们存储在数据部分和只读内存。

2.14.5.12

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementationdefined. The effect of attempting to modify a string literal is undefined.

char* x = "hello world"; 是对 C++ 从早期 C 的继承的倒退。Visual Studio 支持它是因为他们自己的库中有沉重的包袱。