【问题标题】:Should I explicitly cast malloc()'s return value? [duplicate]我应该显式转换 malloc() 的返回值吗? [复制]
【发布时间】:2010-10-31 11:41:19
【问题描述】:

我想问一下下面的案例:

char *temp;
temp = malloc(10);

由于malloc的返回类型是void*,那么malloc返回的指针在赋值给temp之前是否会隐式转换为char*类型?标准对此有何规定?

如果我们的指针变量是某种结构类型,例如:

struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));

如果我们将内存分配给 temp 而不将其转换为 struct node* 类型,它会隐式转换为 struct node* 类型还是需要显式转换为 struct node* 类型?

【问题讨论】:

  • 如果您可能需要使用 C++ 编译器而不是 C 编译器来编译代码,则需要进行强制转换。因此,我的大部分代码都包含显式转换——即使纯 C 不需要它。我通常用 /*=C++=*/ 标记它来说明原因。
  • 虽然没有必要,但对我来说可以帮助我稍后阅读代码,而且不会很冗长。
  • 另见this question

标签: c pointers casting


【解决方案1】:

C 隐式地从void* 转换为void*,因此转换将自动完成。在 C++ 中, void* 的转换只会隐式完成,而对于另一个方向,则需要显式转换。

【讨论】:

  • 注意 C++ 确实支持在没有强制转换的情况下转换为 void *。
【解决方案2】:

可以将 C 中的 void 指针分配给任何指针,而无需显式强制转换。

【讨论】:

  • 我认为它不适用于函数指针。
  • C 未定义是否可以将函数指针转换为非函数指针或返回。 C++明确禁止,C++1x有条件支持
  • 而 POSIX(至少 2008 年)要求函数指针与数据指针大小相同,而 C 标准未定义。
【解决方案3】:

在 C++ 中,您必须显式强制转换,但这实际上只是一种告诉您不要这样做的语言。
在 c 中实际上不需要强制转换,内存只是内存 - 我将不得不进行搜索以查看最新的 C 标准是否需要它。

【讨论】:

  • C99 标准不需要强制转换。
【解决方案4】:

如果您喜欢“不要重复自己”的心态,那么您不需要在 malloc() 调用中重复变量声明中的类型名称应该很有吸引力。因为,正如人们所指出的那样,您不会:指针与void * 之间的转换不会丢失,但函数指针除外。

此外,在此说明中,您也无需重复使用 sizeof。您的第二个示例,在分配结构时,可以这样写:

struct node *temp;
temp = malloc(sizeof *temp);

在我看来,这是最好的方式。

避免重复自己会减少你写的东西的数量,这反过来又会降低任何这些东西出错的风险。

注意sizeof参数中的星号,意思是“这个指针所指向的对象的大小”,当然和“struct node类型的大小”一样,但是没有重复类型姓名。这是因为sizeof 计算(在编译时!)作为其参数的表达式的大小。对于这种情况。就像sizeof 3 计算int 类型表达式的大小一样,sizeof *temp 计算struct node 实例的大小。

当然,您确实会重复 something,即变量名本身,但这通常是一个更简单的表达式,更容易正确,而且编译器也更容易发现错误。

【讨论】:

  • 这是应用 DRY 是一种不安全的编程实践的一个实例(请参阅下面的链接)。避免重复减少错误的论点是上下文相关的。当涉及到 C 中的指针时,它以歧义而臭名昭著,这将导致糟糕的 juju。我宁愿冗长并重复强制转换以在编译时(而不是运行时)发现问题:securecoding.cert.org/confluence/display/seccode/…
  • 像往常一样,securecoding.cert.org 充满了废话。或者,更客气地说,我在那个网站上读过的每一篇文章都充满了不正确的信息(想想ftell vs fstat 一个),被广泛认为是坏和有害的风格,和/或只是简单的货物狂热的“安全”编程。
  • @luis.espinal 嗯?强制转换可以隐藏错误,因为它们明确告诉编译器“这样做!”并且通常会阻止它生成警告,即使您要求的内容似乎是错误的。每当您看到强制转换的 C 代码时,您都需要加倍考虑,如果需要发生什么,以及为什么首先认为强制转换是必要的。如果没有必要,切勿投射。
  • 我个人不喜欢 sizeof(*temp) 表示法。当表达式用作参数时,它有点涉及 sizeof 如何工作(哎呀,您甚至可以使用未定义的函数并且不会出现链接器错误)。在这里它可能会令人困惑,因为通常 * 运算符不适合悬空或空指针。在这里它神奇地起作用。我认为只写 sizeof(struct node) 会更清楚(尤其是对于会偶然发现你的代码的没有经验的程序员)。仅代表我个人意见。
猜你喜欢
  • 2013-12-04
  • 2013-10-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 2015-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多