为什么从string常量转换为'char *'在C中有效,但在C ++中是无效的

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

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

对于C ++来说,这是可以的,因为指向string文字的指针是有害的,因为任何修改它的尝试都会导致崩溃。 但为什么它在C中有效?

C ++ 11也说:

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

这意味着如果一个强制types被添加到第一个语句中,它就会变成有效的。

为什么演员在C ++中使第二个语句有效,与第一个语句有什么不同? 它不是有害的吗? 如果是这样,标准为什么说没关系?

通过C ++ 03,你的第一个例子是有效的,但使用了一个不推荐的隐式转换 – 由于你不能修改它的内容(不会导致未定义的行为),string文字应该被视为char const *types。

从C ++ 11开始,已经被废弃的隐式转换被正式删除了,所以依赖它的代码(就像你的第一个例子)不应该再被编译。

您已经注意到允许代码编译的一种方法:虽然隐式转换已被删除,但显式转换仍然有效,因此您可以添加转换。 但是,我不会考虑这个“修复”的代码。

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

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

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

由于历史原因,它在C中是有效的。 C传统上指定string文字的types是char *而不是const char * ,尽pipe它通过说实际上不允许修改它来限定它。

当你使用转换时,你基本上告诉编译器,你比默认的types匹配规则知道得更多,并且它使得赋值成功。

我得到这个错误的声明:

 static constexpr char* foo = "bar"; 

解决scheme是将其更改为:

 static constexpr char foo[] = "bar";