我什么时候需要用C语言来投射malloc的结果?
这个问题在这里已经有了答案:
对于符合C89或更高版本的任何实现,投射malloc()
的结果是不必要的。
在C语言编程语言第二版的勘误中提到了将malloc()
的结果转换为:
142(第6.5节,接近尾声):有关铸造malloc返回值的说法(“正确的方法是声明...然后明确胁迫”)需要重写。 这个例子是正确的,并且有效,但是建议在1988-1989 ANSI / ISO标准的背景下是有争议的。 这是没有必要的(假设对void *
ALMOSTANYTYPE *
的void *
强制为自动),并且如果malloc
或其代理未能被声明为返回void *
,则可能有害。 明确的转换可以掩盖一个无意的错误。 另一方面,在ANSI之前,演员是必要的,而且它也是用C ++编写的。
(这个链接不再有效,已故的Dennis Ritchie的主页现在在这里;它指向了本书主页的更新位置,但该链接也是无效的。)
最佳做法是将malloc()
调用的结果直接分配给指针对象,并让void*
的隐式转换负责类型一致性。 malloc()
的声明需要通过#include <stdlib.h>
。
(你可能想要在需要显式转换的上下文中使用malloc()
,但我能想到的唯一情况是将malloc()
的结果直接传递给需要参数指针的可变参数类型不是void*
。在这种不寻常的和人为设计的情况下,可以通过将结果赋给指针对象并将该对象的值传递给函数来避免强制转换。)
唯一的好理由来投的结果malloc()
是(a)与C兼容性++(但编写编译都为C和C ++比你想象的更加罕见的代码的需要),以及(b)兼容ANSI前C编译器(但需要迎合这样的编译器很少见,而且越来越少见)。
首先:K&R C是古老的。
其次:我不知道这是否是该例中的完整代码,但在K&R C中,如果没有另外声明,则假定函数具有int
返回值。 如果他没有声明malloc
,那就意味着它就编译器而言返回int
,因此是演员。 请注意,即使在C89(最早的标准版本)中,这也是未定义的行为,并且是非常糟糕的做法; 但为了简洁起见,他可能是这样做的,或者可能是因为懒惰 - 或者出于其他历史原因; 我不知道K&R C的所有错综复杂的情况,也可能是那些void*
char*
演员当时并不隐含。
我应该补充一点,这是一个非常严重的问题,因为int
和void*
可能有不同的大小(并且经常这样做---最常见的例子是大多数x86_64代码,其中指针是64位,但是int是32位) 。
更新: @KeithThompson通知我,代码是从第二版,并malloc
声明那里。 那是一个(不像第一版)仍然相关,如果在地方非常过时。
我猜测演员阵容可能是为了兼容当时非常重要的编译器,因为许多[大多数?]编译器还没有完全符合。 现在,你必须摆脱困境找到一个需要转换的方法(并且不,C ++编译器不计数;它们是C ++编译器,而不是C编译器)。
希望(或可能希望)交叉编译C和C ++的人经常投射malloc(.)
因为C ++不会自动提升void*
。
正如其他人指出的那样,当前的函数原型是可选的,编译器会假定malloc()
返回int
如果它没有看到具有潜在灾难性运行时结果的原型。
我试图在这个论点中看到一些观点,但我简直不敢相信这样的情况会发生,并且有一定的规律可以保证燃烧的人们获得铸造malloc(.)
。
看看在这个网站上投射malloc(.)
任何问题,无论它是什么关于某个人会愤怒地要求他们移除他们的演员,就好像他们让他们的眼睛流血一样。
注意:它没有任何好处,并且没有错的权利投射malloc(.)
所以它是混乱。 实际上,我所知道的唯一(真实的)论点是它引导人们看演员,而不是看论据 - 这是重要的!
我今天在这里看到了代码:
int** x=(int**)malloc(sizeof(int)*n);
被误解为虚假的安全感很容易。 sizeof(int)
正在做(或者在这种情况下做不到)工作以确保从malloc(.)
返回的内容适合于此目的。 (int**)
不起作用。
我不是说投它。 我正在呼吁镇定。 我当然认为,如果一个新手没有给free(.)
打电话,我们会在教会malloc(.)
细微差别之前教给他们这个教训。
上一篇: When do I need to cast the result of malloc in C language?