我正在读一本使用C的书(Butenhof,Programming with POSIX Threads,1997年,我碰到了以下几行:
(void)free(data);
[这里,data
只是指向已分配结构的指针,
data = malloc(sizeof(my_struct_t));
为什么将free
的结果强制转换为void
?
从我对C的理解来看,这似乎没有道理,原因有两个:
void
这本书写于1997年。这是某种遗留的东西吗?
作者提到这些示例在Digital Unix 4.0d上运行,但是如果您不打算使用该结果,我仍然无法想象有理由将其转换为函数的结果。
如果我们在谈论标准的free
函数,则其原型为
void free(void *ptr);
因此,演员表完全没有用。现在有些猜测。
作者可能忘记了包含声明此原型的stdlib.h
标头,因此编译器假定其返回类型为int
。现在,在对该代码进行静态分析时,编译器警告它未使用的返回值(认为它是非void
函数)。通常通过将强制类型转换添加到void
来消除此类警告。
这将是一件古老的事情!
[在有C标准之前,free()
函数本来是(隐式的)类型为int
-因为尚不可靠地返回类型void
。没有返回任何值。
当代码最初被修改为与标准C编译器一起使用时,它可能不包含<stdlib.h>
(因为它在标准之前不存在)。旧代码会为分配函数(类似于extern char *malloc();
和extern
)写calloc()
(可能没有realloc()
),而无需声明free()
。然后代码会将返回值转换为正确的类型-因为至少在某些系统上(包括我在C上学到的系统),这是必需的。
有时,添加(void)
强制转换是为了告诉编译器(或更可能是lint
)“故意忽略了free()
的返回值”,以避免抱怨。但是最好添加<stdlib.h>
并让其声明extern void free(void *vp);
告诉lint
或编译器没有要忽略的值。
JFTR:早在80年代中期,ICL Perq最初是面向字的体系结构,并且内存位置的char *
地址与指向同一位置的“ anything_else指针”相差很大。以某种方式声明char *malloc()
是至关重要的;将结果从其强制转换为任何其他指针类型至关重要。强制转换实际上更改了CPU使用的数字。 (当我们系统上的主内存从1 MiB升级到2 MiB时,也非常高兴。因为内核使用了大约3/4 MiB,这意味着用户程序在分页之前可以使用1 1/4 MiB。) >
不需要此演员表。当时可能还没有,因为C已经以C89的形式进行了标准化。