C++ 为什么从字符串常量转换为';字符*';在C中有效,但在C+中无效+;

C++ 为什么从字符串常量转换为';字符*';在C中有效,但在C+中无效+;,c++,c,string,c++11,char,C++,C,String,C++11,Char,C++11标准(ISO/IEC 14882:2011)在§C.1.1中规定: char* p = "abc"; // valid in C, invalid in C++ 对于C++,它是可以的,因为字符串文字的指针是有害的,因为任何修改它的尝试都会导致崩溃。但是为什么它在C中有效呢 C++11还说: char* p = (char*)"abc"; // OK: cast added 这意味着,如果将强制转换添加到第一条语句中,它将变得有效 为什么在C++中,第二语句的有效性和第一个语句有什

C++11标准(ISO/IEC 14882:2011)在
§C.1.1
中规定:

char* p = "abc"; // valid in C, invalid in C++
对于C++,它是可以的,因为字符串文字的指针是有害的,因为任何修改它的尝试都会导致崩溃。但是为什么它在C中有效呢

C++11还说:

char* p = (char*)"abc"; // OK: cast added
这意味着,如果将强制转换添加到第一条语句中,它将变得有效


为什么在C++中,第二语句的有效性和第一个语句有什么不同?它还有害吗?如果是这样的话,为什么标准说它没问题?

出于历史原因,它在C语言中是有效的。C传统上指定字符串文本的类型为
char*
,而不是
const char*
,尽管它通过声明不允许修改来限定它


当您使用强制转换时,实际上是在告诉编译器您比默认类型匹配规则更了解,这使得赋值可以进行。

直到C++03,您的第一个示例是有效的,但使用了不推荐使用的隐式转换——字符串文本应被视为
char const*
,因为您无法修改其内容(而不会导致未定义的行为)

从C++11开始,不推荐使用的隐式转换被正式删除,因此依赖它的代码(如第一个示例)应该不再编译

您已经注意到允许代码编译的一种方法:尽管隐式转换已被删除,但显式转换仍然有效,因此您可以添加强制转换。然而,我不认为这是对代码的“修复”。

真正修复代码需要将指针的类型更改为正确的类型:

char const *p = "abc"; // valid and safe in either C or C++.

为什么它被允许在C++中(仍然在C中):仅仅因为存在很多依赖于隐式转换的现有代码,并且破坏代码(至少没有一些官方警告)显然对标准委员会来说是个坏主意。

也可以使用扩展:


您可以像以下选项之一一样声明:

char data[] = "Testing String";


C++11不允许使用第一个。我不知道为什么C首先会生成字符串literal
char[]
。第二个是伪装的
const\u cast
。如果此规则被更改,将有太多的遗留C代码被破坏。请引用标准中说第二个是
OK
。C语言在拥有
const
之前就有字符串文本,因此,它们不一定是<代码> const 。C和C++允许您从几乎任何类型转换到另一种类型。这并不意味着这些强制转换是有意义和安全的。它是一个
char[N]
,并被更改为
const char[N]
。在C语言中,字符串文字的类型是
char[N]
,而不是
char*
,例如
“abc”
char[4]
@rullof:它没有提供任何有意义的灵活性,至少对于(根本)关心可移植性的代码来说,这已经够危险的了。在现代操作系统上,写入字符串文字通常会导致程序中止,因此允许代码(尝试)在那里写入并不会增加任何有意义的灵活性是“在C和C++中都是有效和安全的”,而不是“在C或C++中都是有效和安全的”。@DanielLe这两个句子都有相同的意思哦,我的主人!抱歉,这里的“或”是正确的说法。代码可以编译为C或AS C++,但不能同时编译为C和C++。你可以选择任何一个,但你必须做出选择。你不能同时拥有两者。[恢复正常舌部操作]。不,这里最清楚、最正确的措辞是/和。或者正好传达了正确的意思,但从技术上来说,它并不那么清楚。或者单独使用是无可辩驳的错误(A或B不等于A和B)。请注意,
“abc”
被复制,指针
p
应该是
自由的
d以避免内存泄漏。我最初想做一个简单的cast
char*p=(char*)“abcxxxx”
但是我的程序崩溃了,因为我实际上是在稍后修改字符串(我正在使用
mkstemp
替换X)。这个解决方案奏效了。而且我没有忘记免费(p);问题是C和C++在这里有不同的规则。我确信AsKk知道这一点。问题是为什么C和C++在这里有不同的规则。
char data[] = "Testing String";
const char* data = "Testing String";
char* data = (char*) "Testing String";