根据这个
最好不要在C中强制转换malloc,因为如果转换malloc,则会隐藏将被标记的错误,导致很难找到错误.此外,在维护期间,如果指针的类型发生变化但铸件没有改变,则再次发现很难找到错误.最有经验的程序员选择的方法是:
p = malloc ( n * sizeof *p );
Run Code Online (Sandbox Code Playgroud)
malloc没有强制转换,因为不需要一个,而不是使用sizeof(type)来确定块的大小,而是使用sizeof*ptr.通过解除引用指针并获取其大小,可以给出正确的值,而不必担心如果指针的类型改变则修改分配请求.
但它不会在C++中编译.为什么?
这意味着如果malloc的返回被转换,那么将被标记的错误被隐藏?
它不会在C++中编译.为什么?
因为C和C++是不同的语言.
void *C标准允许在其他指针类型之间进行隐式转换.它们不被C++标准所允许.在C中,演员阵容是不必要的,并且没有基本的编程指南"不要重复自己",而在C++中,语言需要演员表(这不是偏好问题).
这是什么意思,如果返回
malloc被强制转换,那么将被标记的错误被隐藏?
隐式函数声明不再是C语言的一部分,但许多编译器继续支持它作为与旧代码库兼容的扩展.如果C函数没有原型,则假定它返回int.如果你无意中忽略#include <stdlib.h>了你的代码但是调用malloc,编译器可能会认为它返回int而不是void *[1].使用显式强制int转换,假定的结果将转换为void *通常可能导致无效指针的结果.这很糟糕,可能导致难以诊断的运行时故障.
另一方面,如果您没有显式强制转换,则在编译时会收到警告或错误,指向错误的确切来源,这更容易诊断和修复.[2]
在实践中,这不是一个问题,malloc而是你自己的函数返回指针(或其他类型),因为许多编译器专门知道malloc并处理它.
在实践中,一些现代编译器实际上会警告你是否有演员阵容,但是肯定仍在使用的编译器如果演员阵容存在则不会发出警告,从而导致合理的偏执狂和防御性编程.
但它不会在C++中编译.为什么?
在void*作为通用指针使用的便利性和防止无效类型转换的安全性之间进行权衡.
在C中,void*被广泛使用,因为它是编写通用代码的唯一合理方式; 因此,在该语言中,为方便起见,它可以隐式转换为另一种指针类型.
在C++中,有类型安全的编写通用代码的方法,因此void*很少使用; 特别是,您使用类型安全new来分配和初始化对象,而不是malloc分配原始内存并假装它包含一个对象.因此,在该语言中,void*禁止隐式转换以提供更强的类型安全性.
并且这意味着如果返回
malloc被投射,那么将被标记的错误被隐藏?
线索在上一句话中:
除非在未包含
stdlib.h声明的标题的情况下,否则没有任何问题malloc
在(较旧的方言)C中,你可以调用一个尚未声明的函数; 隐式声明一个返回类型为的函数int.因此,如果您在malloc不包含标题的情况下进行调用,则会得到错误地认为它返回的代码int.如果没有强制转换,当您尝试将其分配给指针时,会出现编译器错误.使用强制转换,代码将编译,可能会产生模糊的运行时错误和冗长的调试会话.
在C++(和现代C)中,所有函数必须在使用前声明,因此即使您malloc出于某种原因使用了此错误也不会发生.