18

我在较旧的 C 代码中看到了很多以下内容:

type_t *x = (type_t *) malloc(...);

malloc()从它返回的指针转换有什么意义void *?是不是因为较旧的 C 编译器不支持 void 指针并malloc()使用返回char *来代替?

4

4 回答 4

24

你自己的解释是正确的。Pre-ANSI C ('K&R' C) 没有void *隐式转换的类型。char *兼作伪void *类型,但您需要类型转换的显式转换。

在现代 C 中,强制转换是不受欢迎的,因为它可以抑制编译器对malloc. 在 C++ 中,需要进行强制转换(但您应该在大多数情况下使用newmalloc)。

更新

我在下面试图解释为什么需要演员表的评论有点不清楚,我会在这里尝试更好地解释它。您可能会认为即使malloc返回char *,也不需要强制转换,因为它类似于:

int  *a;
char *b = a;

但在这个例子中,还需要一个演员表。第二行是简单赋值运算符 (C99 6.5.1.6.1) 的约束违规。两个指针操作数都必须是兼容的类型。当您将其更改为:

int  *a;
char *b = (char *) a;

约束冲突消失(两个操作数现在都有 type char *)并且结果定义明确(用于转换为 char 指针)。在“相反的情况”中:

char *c;
int  *d = (int *) c;

相同的论点适用于强制转换,但是当int *具有比 更严格的对齐要求时char *,结果是实现定义的。

结论:在 ANSI 之前的日子里,类型转换是必要的,因为malloc返回char *而不是转换结果是对 '=' 运算符的约束违规。

于 2010-08-24T18:24:25.463 回答
7

这里的问题是与 C 的任何方言都不兼容。问题是C++。在 C++ 中,void 指针不能自动转换为任何其他指针类型。因此,如果没有显式强制转换,此代码将无法使用 C++ 编译器进行编译。

于 2010-08-24T18:31:39.550 回答
3

我不知道 malloc 曾经返回过一个 char*。

但并不总是允许从 void* 隐式转换为 type_t* (或任何其他类型)。因此,需要显式转换为正确的类型。

于 2010-08-24T18:21:37.757 回答
-3

由于它是 void *,所以转换从 malloc() 返回的指针有什么意义?

恰恰相反。您需要先将 void 指针转换为实际类型,然后才能使用它,因为 avoid *不表示存储在该位置的数据。

于 2010-08-24T18:23:03.357 回答