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

rul*_*lof 137 c c++ string char c++11

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

char* p = "abc"; // valid in C, invalid in C++
Run Code Online (Sandbox Code Playgroud)

对于C++来说,没关系,因为指向String Literal的指针是有害的,因为任何修改它的尝试都会导致崩溃.但为什么它在C中有效?

C++ 11还说:

char* p = (char*)"abc"; // OK: cast added
Run Code Online (Sandbox Code Playgroud)

这意味着如果将强制转换添加到第一个语句,它将变为有效.

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

Jer*_*fin 165

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

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

您已经注意到允许代码编译的一种方法:虽然隐式转换已被删除,但显式转换仍然有效,因此您可以添加强制转换.但是,我认为这会"修复"代码.

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

char const *p = "abc"; // valid and safe in either C or C++.
Run Code Online (Sandbox Code Playgroud)

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

  • @rullof:它足够危险,它没有提供任何有意义的灵活性,至少对于关心可移植性的代码来说至少是这样.写入字符串文字通常会使程序在现代操作系统上中止,因此允许代码(尝试)在那里写入不会增加任何有意义的灵活性. (8认同)
  • @DanielLe这两个句子都有相同的含义 (4认同)
  • 此答案`char const * p =“ abc”;`中给出的代码段“在** C **和** C ++中均有效且安全”,而不是“在** C **和** C中均有效且安全”。 **或** C ++”。 (3认同)
  • 噢,我的主![将舌头牢牢地插在脸颊上]对不起,但是“或”是正确的术语。可以将代码编译为C或C ++,但不能同时编译为C和C ++。您可以选择其中一个,但是必须做出选择。您不能一次拥有两个。[恢复正常的舌头操作]。 (3认同)
  • 不,* / *是这里最清晰,最正确的措词。* /或*也恰好传达了正确的含义,但从技术上讲并不清楚。* Or *单独是不可避免的错误(* A或B *不等于* A和B *)。 (2认同)
  • @buzhidao:对编译器来说,`char const *` 和`const char *` 是一样的。不同的是`char *const`(它不起作用,出于同样的原因,未经修饰的`char *` 不起作用)。 (2认同)

baz*_*baz 14

您还可以使用strdup

char* p = strdup("abc");
Run Code Online (Sandbox Code Playgroud)

或者

char p[] = "abc";
Run Code Online (Sandbox Code Playgroud)

正如这里所指出的

  • 请注意,“abc”被重复,并且指针“p”应该被“释放”以避免内存泄漏。 (5认同)

Bar*_*mar 11

由于历史原因,它在C中有效.C传统上指定字符串文字的类型char *而不是const char *,虽然它通过说你实际上不允许修改它来限定它.

当你使用强制转换时,你实际上告诉编译器你比默认的类型匹配规则更清楚,并且它使得赋值正常.

  • 它是一个`char [N]`并被改为`const char [N]`.它附有尺寸信息. (3认同)
  • 在 C 中,字符串文字的类型是“char[N]”,但不是“char*”,例如“abc”是“char[4]” (3认同)

Shi*_*yya 7

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

char data[] = "Testing String";
Run Code Online (Sandbox Code Playgroud)

或者

const char* data = "Testing String";
Run Code Online (Sandbox Code Playgroud)

或者

char* data = (char*) "Testing String";
Run Code Online (Sandbox Code Playgroud)

  • 我确信提问者知道这一点;问题是“为什么”C 和 C++ 在这里有不同的规则。 (5认同)