关于`&"hello"`和`"hello"`类型的问题
Question about the type of `&"hello"` and `"hello"`
根据 this code snippet 的输出,&"hello"
的类型是 const char(*)[6]
,因此 char* ptr = &"hello";
对于 char*
和 [=15= 是非法的] 是不同的类型。
并且由于 char* ptr1 = "hello";
使用 C++11 及更高版本编译,"hello"
的类型是 char*
?
如果"hello"
的类型是char*
,那么&"hello"
不应该是指向char*
的指针(即char**
)?
我曾经写过 char* ptr1 = "hello";
很多年,当我知道“hello”是纯右值时。问题是我可以获取字符串literal.After的地址我发现&"hello"
的类型是const char(*)[6]
,我现在一头雾水
有人能解释一下这件事吗?
这是上述代码片段:
#include<memory>
#include<thread>
#include<iostream>
#include<typeinfo>
int main()
{
char* ptr = &"hello";
char* ptr1 = "hello";
}
这是编译器的抱怨:
<source>: In function 'int main()':
<source>:8:17: error: cannot convert 'const char (*)[6]' to 'char*' in initialization
8 | char* ptr = &"hello";
| ^~~~~~~~
| |
| const char (*)[6]
<source>:9:18: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
9 | char* ptr1 = "hello";
| ^~~~~~~
更新:
感谢 ShadowRanger 的澄清。我意识到字符串文字的类型是 const char[6]
.
"Hello"
是类型 const char [6]
的 string literal,由于 类型, 衰减 到 const char*
衰减.
现在让我们看看您程序中的每个语句都发生了什么。
案例一
这里我们考虑语句:
char* ptr = &"hello";
正如我所说,"hello"
是 const char [6]
类型。因此,在其上应用运算符 &
的地址会得到一个 const char (*)[6]
,它被读取为一个 指向大小为 6 且元素类型为 const char
[= 的数组的指针71=].
这意味着右侧(const char (*)[6]
)和左侧(char*
)的类型不匹配。由于没有从 const char (*)[6]
到 char*
的隐式转换,因此编译器给出了上述错误:
cannot convert 'const char (*)[6]' to 'char*'
案例二
这里我们考虑语句:
char* ptr1 = "hello"; //invalid C++
因为 "Hello"
是 const char[6]
类型,这意味着数组中的 char
元素是不可变的(或 non-changable)。正如我所说,类型 const char[6]
衰减为 const char*
。因此在右侧我们有一个 const char*
。因此,如果我们被允许写 char* ptr1 = "Hello";
那么这意味着我们可以更改数组的元素,因为 ptr1
上没有 low-level const
。因此,允许 char* ptr1 = "Hello";
将允许更改标记为 const
的数据,这不应该发生(因为数据不应更改,因为它被标记为 const
)。这就是为什么提到的警告说:
ISO C++ forbids converting a string constant to 'char*'
因此,为了防止这种情况发生,我们必须添加一个 low-level const
,如下所示:
vvvvv---------------------------> note the low-level const
const char* ptr1 = "Hello"; //valid c++
这样就不允许指针ptr1
改变const
标记的数据。
通过添加上面突出显示的 low-level const
,这意味着我们不允许更改数组的基础字符。
根据 this code snippet 的输出,&"hello"
的类型是 const char(*)[6]
,因此 char* ptr = &"hello";
对于 char*
和 [=15= 是非法的] 是不同的类型。
并且由于 char* ptr1 = "hello";
使用 C++11 及更高版本编译,"hello"
的类型是 char*
?
如果"hello"
的类型是char*
,那么&"hello"
不应该是指向char*
的指针(即char**
)?
我曾经写过 char* ptr1 = "hello";
很多年,当我知道“hello”是纯右值时。问题是我可以获取字符串literal.After的地址我发现&"hello"
的类型是const char(*)[6]
,我现在一头雾水
有人能解释一下这件事吗?
这是上述代码片段:
#include<memory>
#include<thread>
#include<iostream>
#include<typeinfo>
int main()
{
char* ptr = &"hello";
char* ptr1 = "hello";
}
这是编译器的抱怨:
<source>: In function 'int main()':
<source>:8:17: error: cannot convert 'const char (*)[6]' to 'char*' in initialization
8 | char* ptr = &"hello";
| ^~~~~~~~
| |
| const char (*)[6]
<source>:9:18: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
9 | char* ptr1 = "hello";
| ^~~~~~~
更新:
感谢 ShadowRanger 的澄清。我意识到字符串文字的类型是 const char[6]
.
"Hello"
是类型 const char [6]
的 string literal,由于 类型, 衰减 到 const char*
衰减.
现在让我们看看您程序中的每个语句都发生了什么。
案例一
这里我们考虑语句:
char* ptr = &"hello";
正如我所说,"hello"
是 const char [6]
类型。因此,在其上应用运算符 &
的地址会得到一个 const char (*)[6]
,它被读取为一个 指向大小为 6 且元素类型为 const char
[= 的数组的指针71=].
这意味着右侧(const char (*)[6]
)和左侧(char*
)的类型不匹配。由于没有从 const char (*)[6]
到 char*
的隐式转换,因此编译器给出了上述错误:
cannot convert 'const char (*)[6]' to 'char*'
案例二
这里我们考虑语句:
char* ptr1 = "hello"; //invalid C++
因为 "Hello"
是 const char[6]
类型,这意味着数组中的 char
元素是不可变的(或 non-changable)。正如我所说,类型 const char[6]
衰减为 const char*
。因此在右侧我们有一个 const char*
。因此,如果我们被允许写 char* ptr1 = "Hello";
那么这意味着我们可以更改数组的元素,因为 ptr1
上没有 low-level const
。因此,允许 char* ptr1 = "Hello";
将允许更改标记为 const
的数据,这不应该发生(因为数据不应更改,因为它被标记为 const
)。这就是为什么提到的警告说:
ISO C++ forbids converting a string constant to 'char*'
因此,为了防止这种情况发生,我们必须添加一个 low-level const
,如下所示:
vvvvv---------------------------> note the low-level const
const char* ptr1 = "Hello"; //valid c++
这样就不允许指针ptr1
改变const
标记的数据。
通过添加上面突出显示的 low-level const
,这意味着我们不允许更改数组的基础字符。