对malloc返回的指针进行类型转换是一种更好的做法吗?
对于下面的C代码,比较int指针a和b的定义;
#include #include int main() { int *a=malloc(sizeof(int)); int *b=(int *)malloc(sizeof(int)); return(0); }
以任何方式更好地对malloc函数返回的类型为void的指针进行类型转换? 或者在分配到左侧的int指针时是自动类型化的吗? 在哪种情况下,如果有的话,它是否可以certificate是必要的而不仅仅是强制性的?
请说明隐式类型转换,右侧类型转换为左侧类型,是否适用于此处。
C语言不需要强制转换,但是对于C ++兼容性,您可能需要强制转换。 这是C不是C ++子集的地方之一。
以下将在C中编译但不在C ++中编译:
int *a=malloc(sizeof(int));
以下将在C和C ++中编译:
int *b=(int *)malloc(sizeof(int));
不,是的,从不
- 有人投了指针,我没有。
- 是的,类型转换“自动”发生
- 它在C中永远不必要。
- 以一种奇怪的方式,转换结果会影响 C ++的可移植性。 从C ++引用的模块很可能被编译为C,在这种情况下它无关紧要。 但是如果代码以某种方式被复制并粘贴到C ++中,我认为你希望每个这样的行都被标记,因为在C ++中调用malloc()的一行代码是一个可疑的LoC。
- 在某种程度上,这是早期K&R C的延续,它没有像
void
这样的类型,所以malloc()
返回了一个char *
。 现在,你需要做演员表。 因此,铸造malloc()
的设计模式开发并影响了编写下一组代码的所有人,并且人们仍然在阅读这些代码体,并将模式向前推进。 但C89无效,所以是时候简化代码了。 - 根据它的确切方式,演员表可能会违反DRY(又称DIE)。正如Chris Lutz指出的那样,它会不必要地降低抽象级别。 因为在C程序中,这并不是天高的,所以我宁愿不要失去我们所拥有的水平。
简而言之:
如果您已经包含了stdlib.h
,那么该模型绝对没有任何内容,应该删除。 毕竟,您已经指定了类型。
如果你还没有,那么演员将掩盖错误,这是不好的。
切勿在C代码中使用该转换。
在C ++中,强制转换是必要的,因为C ++不允许void *
和其他指针类型之间的隐式转换。 另一方面,在C ++中,有比malloc()
更好的东西,比如new
或容器类。
编写将在其中编译的代码毫无意义。 你应该总是知道你正在写什么语言,并且在子集中写入会强迫你使用一种在任何一种语言中都较差的结构。 我熟悉的C ++编译器也将编译C代码,C ++中有明确的规定可以轻松地与C代码链接。 如果您将其编译为C ++,则错误消息(没有强制转换)将指出您的错误。
所有演员都会做的是掩盖可以在其他地方咬你的错误。 它不会做任何有用的事情。 不要这样做。
在C中,演员阵容是不必要的。 malloc
返回void*
,C标准声明:
指向void的指针可以转换为指向任何不完整或对象类型的指针。 指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针。
此外,K&R2说:
任何指向对象的指针都可以转换为void *类型而不会丢失信息。 如果结果转换回原始指针类型,则恢复原始指针。 与Par.A.6.6中讨论的指针到指针转换(通常需要显式转换)不同,指针可以分配给void *类型的指针,也可以与它们进行比较。
关于C ++兼容性可能有一点,因为在C ++中,强制转换是强制性的。 然而,恕我直言这是不相关的,因为惯用的C ++无论如何都要求使用new
而不是malloc
。
转换malloc()
的返回值是一个C ++习惯用法,在C代码中没有位置。 只有当你想要将代码编译为C ++时才有必要,你不应该这样做,因为C和C ++是具有不同语义的不同语言。
只有你想创建一个C库来定义头文件中的内联函数才能从C ++中使用它才有意义。 随着链接时优化的出现,这种希望不再是必要的,因为即使在不同的源文件中定义函数也可以内联。
对于声称显式强制转换增加可读性的人,请考虑给定的示例
int *b=(int *)malloc(sizeof(int));
如何重复三次类型更可读
int *b = malloc(sizeof *b);
超出我的范围。
C ++ 0x甚至添加了类型推断来摆脱类似的重复,所以我并不认为这是有争议的。
如果我们正在谈论C,最佳做法是不要转换 malloc()
的结果。 如果我们在谈论C ++,最佳做法是使用new
而不是malloc()
1 。
我建议不要强制转换结果的原因是为了避免在#include
stdlib.h中出现问题,或者在范围内没有malloc()
的原型。 直到C99,如果你有一个没有事先声明的函数调用,编译器会隐式键入函数调用以返回int
。 如果没有强制转换,这将导致不兼容的分配警告。 使用强制转换,警告被抑制,并且可能会导致运行时错误,因为从malloc()
返回的值将从指针转换为int并再次返回指针,这不能保证有意义。
- 如果你从C语言移植到C ++,你也可以从
malloc()
转换到new
前端。
以任何方式更好地对malloc函数返回的类型为void的指针进行类型转换?
是。 它的含义更清晰。 这和我写的原因是一样的
a = b + (c * d);
现在,我知道这里不需要“()”,因为算术运算符的优先级规则,但它们帮助我(和其他人)清楚地看到我的意图。
$ .02等:)
-k