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

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

但是C ++禁止它。

 int *a = malloc(4); 

导致此错误:

 invalid conversion from 'void*' to 'int*' [-fpermissive] 

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

有没有c ++的例子?

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

 int *a = (int *)malloc(sizeof(int)); 

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

编辑:正如评论中所建议的那样, malloc()的使用不应该是司空见惯的。 最接近的选择是使用new来分配。

 int *a = new int[15]; 

附加编辑:正如评论中再次建议的那样,如果必须使用malloc() ,至少要使用C ++强制转换。

 int *a = static_castmalloc(sizeof(int)); // shout out to @edheal, @mgetz 

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

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

 int x; void *p = &x; double *q = p; *q = 0.0; 

如果源代码中没有任何强制转换,则违反了类型安全性。

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

C ++不禁止转换; 它只是想通过源代码中的某种模糊来记录它,即至少表明,如果没有certificate,它是故意的。

关于void *的起源, Stroustrup写了这个 (bolding mine):

在其历史的后期,C with Classes *开始支持指向”raw memory, void *的指针的概念。 void *的起源笼罩在一些神秘之中。 我依旧记得与Larry Rosler和Steve Johnson一起发明它。 然而,Dave Prosser记得首先根据“在澳大利亚的某个地方使用过的东西”提出建议。 可能两个版本都是正确的,因为戴夫当时与拉里密切合作。 在任何一种情况下, void * 都会或多或少地同时引入两种语言 。 我能找到的最早提到的void *是在1983年1月1日的备忘录中,关于我的C ++编译器Cfront提供的内存管理机制,所以C ++中void *的起源必须至少回溯到1982年中期。 。 在ANSI C的背景下,最早的void *书面记录是迈克迈斯纳提出的“10月12日晚期”的提案,其提出的void *基本上是因为它在1984年6月被ANSI C接受[Prosser,2001]

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

malloc的情况下,当然存在危险; 但是那些已经被众所周知的标识符malloc的存在所标记; 演员阵容不会带来任何更多,但不要求它专门用于malloc ,而在其他地方要求它将是规则的一个尴尬的例外。


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