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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20944784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:25:03  来源:igfitidea点击:

Why is conversion from string constant to 'char*' valid in C but invalid in C++

c++cstringc++11char

提问by rullof

The C++11 Standard (ISO/IEC 14882:2011) says in § C.1.1:

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

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

For the C++ it's OK as a pointer to a String Literal is harmful since any attempt to modify it leads to a crash. But why is it valid in C?

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

The C++11 says also:

C++11 还说:

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

Which means that if a cast is added to the first statement it becomes valid.

这意味着如果将强制转换添加到第一个语句中,它就会变得有效。

Why does the casting makes the second statement valid in C++ and how is it different from the first one? Isn't it still harmful? If it's the case, why did the standard said that it's OK?

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

回答by Jerry Coffin

Up through C++03, your first example was valid, but used a deprecated implicit conversion--a string literal should be treated as being of type char const *, since you can't modify its contents (without causing undefined behavior).

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

As of C++11, the implicit conversion that had been deprecated was officially removed, so code that depends on it (like your first example) should no longer compile.

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

You've noted one way to allow the code to compile: although the implicit conversion has been removed, an explicitconversion still works, so you can add a cast. I would not, however, consider this "fixing" the code.

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

Truly fixing the code requires changing the type of the pointer to the correct type:

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

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

As to why it was allowed in C++ (and still is in C): simply because there's a lot of existing code that depends on that implicit conversion, and breaking that code (at least without some official warning) apparently seemed to the standard committees like a bad idea.

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

回答by Barmar

It's valid in C for historical reasons. C traditionally specified that the type of a string literal was char *rather than const char *, although it qualified it by saying that you're not actually allowed to modify it.

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

When you use a cast, you're essentially telling the compiler that you know better than the default type matching rules, and it makes the assignment OK.

当您使用强制转换时,您实际上是在告诉编译器您比默认类型匹配规则更了解,并且它使分配正常。

回答by baz

You can also use strdup:

您还可以使用strdup

char* p = strdup("abc");