0

过去我一直在使用 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] },对此也有任何解释吗?谢谢!

4

2 回答 2

6

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

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

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

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

由于someString它是程序数据存储器中的一个数组,因此可以写入它,并且它不需要是 const 限定的。

于 2016-07-10T17:30:17.950 回答
2

根据标准:附件C(兼容性)

C1.1 子条款 2.14.5:

更改:字符串文字变为 const

字符串文字的类型从“char 数组”更改为“const char 数组”。char16_t 字符串文字的类型从“一些整数类型的数组”更改为“const char16_t 的数组”。char32_t 字符串字面量的类型从“array of some-integer-type”更改为“array of const char32_t”。</p>

宽字符串字面量的类型从“array of wchar_t”更改为“array of const wchar_t”。</p>

基本原理:这避免了调用不适当的重载函数,该函数可能期望能够修改其参数。

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

普通字符串文字和 UTF-8 字符串文字也称为窄字符串文字。窄字符串文字的类型为“n const char 数组”,其中 n 是字符串的大小,定义如下,并且具有静态存储持续时间

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

2.14.5.12

是否所有字符串文字都是不同的(即存储在不重叠的对象中)是实现定义的。尝试修改字符串文字的效果是未定义的。

char* x = "hello world";是对 C++ 从早期 C 的继承的回归。Visual Studio 支持它,因为它们自己的库中的包袱很重。

于 2016-07-10T18:17:43.133 回答