转换void指针
我在旧的C代码中看到了很多以下内容:
type_t *x = (type_t *) malloc(...);
从malloc()
返回指针的重点是什么,因为它是void *
? 是因为较旧的C编译器不支持void指针而malloc()
用于返回char *
而不是?
你自己的解释是正确的。 预ANSI-C(’K&R’C)没有带隐式转换的void *
类型。 char *
doubled作为伪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;
约束违反消失(两个操作数现在都有char *
类型),结果定义良好(转换为char指针)。 在“反向情况”:
char *c; int *d = (int *) c;
对于转换,相同的参数保持,但是当int *
具有比char *
更严格的对齐要求时,结果是实现定义的 。
结论:在ANSI之前的日子里,类型转换是必要的,因为malloc
返回char *
而不是转换结果是对’=’运算符的约束违反。
这里的问题是与C的任何方言不兼容。问题是C ++ 。 在C ++中,void指针不能自动转换为任何其他指针类型。 因此,如果没有显式强制转换,此代码将无法使用C ++编译器进行编译。
我不知道malloc曾经返回过char *。
但是并不总是允许从void *到type_t *(或任何其他类型)的隐式转换。 因此,需要明确地转换为正确的类型。
从malloc()返回指针的重点是什么,因为它是无效的*?
恰恰相反。 在使用它之前, 需要将void指针强制转换为实际类型,因为void *
表示存储在该位置的数据。