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

时间:2014-04-18 00:46:14

标签: c++ c

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

但是C ++禁止它。

int *a = malloc(4);

导致此错误:

invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]

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

有没有c ++的例子?

3 个答案:

答案 0 :(得分:8)

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

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

关于此强制演员及其背后原因的精彩文章can be found here.
参考can be found here.

的其他链接

修改:根据评论中的建议,malloc()的使用不应该是司空见惯的。最接近的替代方法是使用new进行分配。

int *a = new int[15];

其他编辑:正如评论中所建议的那样,如果您必须使用malloc(),至少要使用C ++演员。

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

答案 1 :(得分:3)

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

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

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

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

这是C++ FAQ answered by B. Stroustrup, inventor of C++

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

关于void *Stroustrup writes this(加粗地雷)的来源:

  

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

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

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


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

答案 2 :(得分:0)

在 C++ 中,如果您使用 malloc,您应该在 malloc 返回的存储中构造您的对象。如果你只是转换结果,你的程序有未定义的行为。

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

但大多数情况下,您不应该在 C++ 中调用 malloc。您不应该使用带有所指向对象所有权的原始指针。

auto a = std::make_unique<int>();