7 回答
TA贡献1856条经验 获得超11个赞
无 ; 你没有投射结果,因为:
这是不必要的,因为
void *
在这种情况下自动且安全地提升到任何其他指针类型。它增加了代码的混乱,转换不是很容易阅读(特别是如果指针类型很长)。
它让你重复自己,这通常很糟糕。
如果您忘记包含,它可以隐藏错误
<stdlib.h>
。这可能会导致崩溃(或更糟的是,不导致崩溃,直到方式在后面的代码的一些完全不同的部分)。考虑如果指针和整数的大小不同会发生什么; 那么你通过强制转换隐藏了一个警告,可能会丢失你返回的地址。注意:从C11开始,隐式函数从C中消失,并且这一点不再相关,因为没有自动假设未声明的函数返回int
。
作为澄清,请注意我说“你不投”,而不是“你不需要投”。在我看来,即使你做对了也没有包括演员。这样做没有任何好处,但是一堆潜在的风险,包括演员表明你不知道风险。
还要注意,正如评论员指出的那样,上面谈的是直C,而不是C ++。我非常坚信C和C ++是不同的语言。
要进一步添加,您的代码会不必要地重复int
可能导致错误的类型信息()。最好取消引用用于存储返回值的指针,将两者“锁定”在一起:
int *sieve = malloc(length * sizeof *sieve);
这也会移动length
到前面以增加可见性,并删除多余的括号sizeof
; 只有在参数是类型名称时才需要它们。许多人似乎不知道(或忽略)这一点,这使得他们的代码更加冗长。记住:sizeof
不是功能!:)
虽然移动length
到前面可能会增加在某些极少数情况下的可见性,但是在一般情况下,应该注意将表达式编写为:
int *sieve = malloc(sizeof *sieve * length);
因为sizeof
在这种情况下保持第一个,所以确保乘法至少用size_t
数学来完成。
比较:malloc(sizeof *sieve * length * width)
与malloc(length * width * sizeof *sieve)
第二个可能溢出的length * width
时间width
和length
比较小的类型size_t
。
TA贡献1869条经验 获得超4个赞
在C中,您不需要转换返回值malloc
。返回的void指针malloc
自动转换为正确的类型。但是,如果您希望使用C ++编译器编译代码,则需要进行强制转换。社区中的首选替代方案是使用以下内容:
int *sieve = malloc(sizeof *sieve * length);
如果你改变了类型,你还可以免去担心改变表达式的右侧sieve
。
人们已经指出,演员阵容很糟糕。特别是指针转换。
TA贡献1830条经验 获得超3个赞
你做演员,因为:
它使您的代码在C和C ++之间更具可移植性,并且正如SO经验所示,许多程序员声称他们在用C ++(或C加本地编译器扩展)编写时正在用C语言编写。
如果不这样做可以隐藏错误:注意所有的混乱的SO例子,当写
type *
对type **
。它让你不会注意到你没有找到
#include
合适的头文件的想法错过了森林的树木。这就像说“不要担心你没有要求编译器抱怨没有看到原型这一事实 - 那令人讨厌的stdlib.h是真正重要的事情要记住!”它强制进行额外的认知交叉检查。它将(声称的)所需类型放在您正在为该变量的原始大小进行的算术旁边。我敢打赌你可以做一个SO研究,它表明
malloc()
当有一个演员时,bug会被抓得更快。与断言一样,显示意图的注释可以减少错误。以机器可以检查的方式重复自己通常是一个好主意。事实上,这就是一个断言,并且使用强制转换是一种断言。断言仍然是我们获得正确代码的最常用技术,因为图灵在很多年前提出了这个想法。
TA贡献1802条经验 获得超6个赞
正如其他人所说,C不是必需的,而是C ++。如果您认为要使用C ++编译器编译C代码,出于某种原因,您可以使用宏,例如:
#ifdef __cplusplus# define NEW(type, count) ((type *)calloc(count, sizeof(type)))#else# define NEW(type, count) (calloc(count, sizeof(type)))#endif
这样你仍然可以以非常紧凑的方式编写它:
int *sieve = NEW(int, 1);
它将为C和C ++编译。
TA贡献1801条经验 获得超8个赞
在C中,您可以隐式地将void指针转换为任何其他类型的指针,因此不需要强制转换。使用一个人可能会向不经意的观察者建议,有一些理由需要一个,这可能会产生误导。
TA贡献1821条经验 获得超4个赞
你没有强制转换malloc的结果,因为这样做会给你的代码带来无意义的混乱。
人们投射malloc结果的最常见原因是因为他们不确定C语言是如何工作的。这是一个警告信号:如果您不知道特定语言机制的工作原理,那么请不要猜测。查找或询问Stack Overflow。
一些评论:
可以将void指针转换为/从任何其他指针类型转换而不进行显式转换(C11 6.3.2.3和6.5.16.1)。
但是,C ++不允许在
void*
另一个指针类型之间进行隐式转换。所以在C ++中,演员阵容是正确的。但是如果你用C ++编程,你应该使用new
而不是malloc()。而且你永远不应该使用C ++编译器编译C代码。如果需要使用相同的源代码同时支持C和C ++,请使用编译器开关来标记差异。不要尝试使用相同的代码来区分两种语言标准,因为它们不兼容。
如果C编译器由于忘记包含头而无法找到函数,那么您将收到编译器/链接器错误。因此,如果您忘记包含
<stdlib.h>
那些没什么大不了的话,那么您将无法构建您的程序。对于遵循超过25年的标准版本的古代编译器,忘记包含
<stdlib.h>
将导致危险的行为。因为在那个古老的标准中,没有可见原型的函数隐式地将返回类型转换为int
。然后显式地从malloc转换结果将隐藏此错误。但这确实不是问题。您没有使用25年的计算机,那么为什么要使用25年的编译器呢?
- 7 回答
- 0 关注
- 608 浏览
添加回答
举报