我在较旧的 C 代码中看到了很多以下内容:
type_t *x = (type_t *) malloc(...);
malloc()
从它返回的指针转换有什么意义void *
?是不是因为较旧的 C 编译器不支持 void 指针并malloc()
使用返回char *
来代替?
我在较旧的 C 代码中看到了很多以下内容:
type_t *x = (type_t *) malloc(...);
malloc()
从它返回的指针转换有什么意义void *
?是不是因为较旧的 C 编译器不支持 void 指针并malloc()
使用返回char *
来代替?
你自己的解释是正确的。Pre-ANSI C ('K&R' C) 没有void *
隐式转换的类型。char *
兼作伪void *
类型,但您需要类型转换的显式转换。
在现代 C 中,强制转换是不受欢迎的,因为它可以抑制编译器对malloc
. 在 C++ 中,需要进行强制转换(但您应该在大多数情况下使用new
它malloc
)。
我在下面试图解释为什么需要演员表的评论有点不清楚,我会在这里尝试更好地解释它。您可能会认为即使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 *
而不是转换结果是对 '=' 运算符的约束违规。
这里的问题是与 C 的任何方言都不兼容。问题是C++。在 C++ 中,void 指针不能自动转换为任何其他指针类型。因此,如果没有显式强制转换,此代码将无法使用 C++ 编译器进行编译。
我不知道 malloc 曾经返回过一个 char*。
但并不总是允许从 void* 隐式转换为 type_t* (或任何其他类型)。因此,需要显式转换为正确的类型。
由于它是 void *,所以转换从 malloc() 返回的指针有什么意义?
恰恰相反。您需要先将 void 指针转换为实际类型,然后才能使用它,因为 avoid *
不表示存储在该位置的数据。