在讨论malloc
的过程中,许多人声称malloc
的隐式声明会导致返回值被转换为int
,然后再转换回T*
,可能会导致指针在以下情况下被截断:
sizeof(int) < sizeof(void*)
这将意味着编译器执行以下操作:
malloc
的正确目标代码真的有人能证明这事发生了吗?比如在64位Linux上使用一些示例代码?
我会自己做的,但我没有64位机器的权限。
发布于 2009-10-14 13:20:02
Malloc是在stdlib.h
文件头中声明的,声明由源代码的C预处理器直接包含,然后在以后的阶段与malloc代码链接。
当您有代码时:
#include <stdlib.h>
...
void * foo = malloc(42);
它实际上被加工成类似于
...
extern void *malloc (size_t __size) __attribute__ ((__nothrow__)) __attribute__ ((__malloc__)) ;
(...lots of other declarations...)
...
void * foo = malloc(42);
当您不包括函数原型时,它默认为
int malloc();
...
void * foo = malloc(42);
这意味着最终编译的代码将执行类似的操作,“使用参数42调用malloc
,将其返回值从int转换为void*,并将其转换为foo
”。然后,它将与带有malloc预编译对象代码的libc链接,这显然是无效的*-返回。因此,结果将是在保存返回值的CPU寄存器上进行一次额外的int*转换。我设想在64位架构上,它可能意味着接受较低的32位,并在前面放置32个零,从而清除部分原始指针。
发布于 2009-10-14 13:28:31
我认为2并不像你所暗示的那样是一种“宝贵”的转换。当使用返回类型未知的函数进行数据处理时,编译器必须对要“获取”的字节数做出一些假设。默认值是int的大小。
所以,如果一个空*和一个int恰好是相同的大小,那么,好的,如果不是oops!
发布于 2009-10-14 14:01:05
通过省略malloc
的声明(prototype),编译器假定它返回int
。因此,对它的调用作为代码生成,以调用返回int
结果的函数。
根据系统的不同,这样做的方式不同,因此结果可能会在数据寄存器、地址寄存器或堆栈中被传回。
然后,编译器生成额外的代码,以将(推定的)返回的int
值转换为指针。
很明显,这不是你想要的。在大多数系统上,您可能会很幸运,因为在这些系统中,ints和指针的宽度是相同的,因此返回值的转换基本上没有任何作用,但是不能依赖这种行为。
总之,--不声明外部函数是一件坏事。
https://stackoverflow.com/questions/1566107
复制相似问题