为什么从字符串转换为'char*'在C中有效但在c++中无效

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

char* p = "abc"; // valid in C, invalid in C++

对于c++,它是OK的,因为指向字符串文字的指针是有害的,因为任何修改它的尝试都会导致崩溃。但为什么它在C中成立?

c++ 11还说:

char* p = (char*)"abc"; // OK: cast added

这意味着如果在第一个语句中添加了强制转换,它就会生效。

为什么强制转换使第二个语句在c++中有效,它与第一个语句有什么不同?它不是仍然有害吗?如果是这样,为什么标准说这是可以的?

235636 次浏览

由于历史原因,它在C语言中是有效的。C语言传统上指定字符串字面值的类型是char *而不是const char *,尽管它通过说你实际上不允许修改它来限定它。

当你使用类型转换时,你实际上是在告诉编译器你知道的比默认的类型匹配规则更好,它让赋值操作OK。

直到c++ 03,你的第一个例子是有效的,但使用了不推荐的隐式转换——字符串字面值应该被视为char const *类型,因为你不能修改它的内容(而不会导致未定义的行为)。

从c++ 11开始,已经弃用的隐式转换被正式移除,因此依赖于它的代码(如您的第一个示例)应该不再编译。

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

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

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

至于为什么它在c++中被允许(在C中仍然是):简单地说,因为有很多现有的代码依赖于这种隐式转换,而破坏这种代码(至少在没有任何官方警告的情况下)显然对标准委员会来说是个坏主意。

你也可以使用第6行的:

char* p = strdup("abc");

char p[] = "abc";

作为指向在这里

你可以像下面的选项一样进行声明:

char data[] = "Testing String";

const char* data = "Testing String";

char* data = (char*) "Testing String";