为什么c ++禁止隐式转换void*?

Sam*_*Sam 7 c c++

在C中,我们可以转换void*为任何其他指针.

但是C++禁止它.

int *a = malloc(4);
Run Code Online (Sandbox Code Playgroud)

导致此错误:

invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

c ++中有潜在的危险吗?

有没有c ++的例子?

Bri*_*acy 9

在C++中,与C不同,您必须转换 malloc的结果.您的代码可以通过简单的强制转换调整为工作顺序.

int *a = (int *)malloc(sizeof(int));
Run Code Online (Sandbox Code Playgroud)

这里有一篇关于强制演员及其背后原因的精彩文章.可在此处找到
另一个供参考的链接.

编辑:正如评论中所建议的那样,使用不malloc()应该是司空见惯的.最接近的替代方案是使用new分配.

int *a = new int[15];
Run Code Online (Sandbox Code Playgroud)

附加编辑:正如评论中再次提出的,如果必须使用malloc(),至少使用C++强制转换.

int *a = static_cast<int*>malloc(sizeof(int)); // shout out to @edheal, @mgetz
Run Code Online (Sandbox Code Playgroud)

  • 正如OP观察到的那样.他询问为什么要做出设计决定. (2认同)
  • @Mgets 无论如何,这都是没有意义的,因为不存在限定符被删除之类的风险。当源是“void *”时,“(int *)”不会不恰当地选择比预期更强大的强制转换方法。现在,如果您从“const void *”开始,您就明白了一点:C 转换将更改类型并删除限定符。 (2认同)

Kaz*_*Kaz 5

您可以在 C++ 中进行转换,但它需要强制转换。C++ 旨在成为一种比 C 更类型安全的语言,因此它试图弥补 C 允许的一些“类型系统中的漏洞”。

在 C 中,这将被接受而无需任何诊断:

int x;
void *p = &x;
double *q = p;
*q = 0.0;
Run Code Online (Sandbox Code Playgroud)

在源代码中没有任何强制转换的情况下违反了类型安全。

这是C++ 的发明者 B. Stroustrup 回答C++ FAQ

C++ 不禁止转换;它只是希望通过源代码中的某种简介来记录它,即至少表明(如果不能证明的话)它是故意完成的。

关于 的起源void *Stroustrup 写道(加粗我的):

在其历史后期,带有类* 的C开始支持指向“原始内存”的指针的概念,void *. 的起源void *被一些谜团所笼罩。我依稀记得与 Larry Rosler 和 Steve Johnson 一起发明了它。然而,Dave Prosser 记得最初是根据“澳大利亚某处”使用的东西提出的。可能两个版本都是正确的,因为当时 Dave 与 Larry 密切合作。在任何一种情况下,void * 都或多或少地同时被引入两种语言void *我能找到的最早提及是在 1983 年 1 月 1 日的备忘录中,关于我的 C++ 编译器 Cfront 提供的内存管理机制,因此void *在 C++ 中必须至少追溯到 1982 年中期。void * ANSI C 上下文中最早的书面记录是 Mike Meissner 于“83 年 10 月 12 日”提出的提案,该提案void *基本上是在 1984 年 6 月被 ANSI C 接受时提出的[Prosser,2001]

所以 C++ 继承了void *Stroustrup 最初设想的概念,而大约在同一时间,C 人有一个稍微不同的想法,在类型安全方面更加宽松。

在的情况下malloc,当然有危险;但是那些已经被众所周知的标识符标记了malloc;演员表不会再带来任何东西,但不需要专门用于malloc,而在其他任何地方都需要它会是规则的尴尬例外。


* “C with Classes”是C++的前身