c – 我输入malloc的结果吗?

在这个问题,有人建议意见,我应该不会投的结果malloc,即

int *sieve = malloc(sizeof(int) * length);

而不是:

int *sieve = (int *) malloc(sizeof(int) * length);

为什么会这样呢?


 ; 你不会投出结果,因为:

  • 这是没有必要的,因为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时间widthlength比较小的类型size_t


在C中,你不需要转换返回值malloc。返回的void指针malloc被自动转换为正确的类型。但是,如果您希望使用C ++编译器编译代码,则需要执行强制转换。社区中的首选替代方案是使用以下内容:

int *sieve = malloc(sizeof *sieve * length);

如果您改变表达式的类型,它还使您不必担心更改表达式的右侧sieve

正如人们已经指出的那样,演员阵容糟糕。特别指针转换。


投,这是因为:

  • 它使得你的代码更易于在C和C ++之间移植,正如SO经验显示的那样,许多程序员声称当他们真正使用C ++(或C +本地编译器扩展)编写时,他们正在使用C编写代码。
  • 如果不这样做,可能会隐藏一个错误:请注意所有的SO例子,以便type *与写时相比较type **
  • 这个想法让你没有注意到你没有#include合适的头文件会错过树林。这与“不要担心你没有要求编译器抱怨没有看到原型 – 这个令人讨厌的stdlib.h是真正重要的事情要记住!”
  • 它强制进行额外的认知交叉检查。它将(所谓的)期望类型放在您为该变量的原始大小进行的算术旁边。我敢打赌,你可以做一个SO研究,这个研究表明,malloc()在演员阵容中,错误被抓得更快。与断言一样,可以揭示意图的注释可以减少错误。
  • 以机器可以检查的方式重复自己往往是一个主意。事实上,这就是一个断言,这种使用是一个断言。自从Turing在多年前提出这个想法以来,断言仍然是我们获得代码正确性的最通用技术。

正如其他人所说的那样,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 ++。

Tags:, ,

添加评论

友情链接:蝴蝶教程