简体   繁体   English

为什么将 free 的返回值转换为 void?

[英]Why cast free's return value to void?

I am reading a book ( Programming with POSIX Threads by Butenhof, 1997) that uses C, and I came across the following line:我正在阅读一本使用 C 的书(Butenhof 的POSIX 线程编程,1997 年),我遇到了以下行:

(void)free(data);

Here, data is just a pointer to an allocated struct,在这里, data只是一个指向已分配结构的指针,

data = malloc(sizeof(my_struct_t));

Why is the result of free being cast to void ?为什么free被强制转换为void的结果?

From my understanding of C, this doesn't seem to make sense for two reasons:根据我对 C 的理解,这似乎没有意义,原因有两个:

  • The free function already returns void free 函数已经返回void
  • The code is not using the return value (it's not even being assigned to a variable)代码没有使用返回值(它甚至没有被分配给一个变量)

The book was written in 1997. Is this some sort of legacy thing?这本书写于 1997 年。这是某种遗产吗?

The author mentions that the examples were run on Digital Unix 4.0d, but I still can't imagine a reason to ever cast the result of a function if you're not going to use that result.作者提到这些示例是在 Digital Unix 4.0d 上运行的,但如果您不打算使用该结果,我仍然无法想象有理由强制转换该函数的结果。

If we are talking about the standard free function then its prototype is如果我们谈论的是标准的free函数,那么它的原型是

void free(void *ptr);

Therefore the cast is completely useless.因此演员表完全没用。
Now some speculation.现在有些猜测。

The author might have forgotten to include the stdlib.h header declaring this prototype, so the compiler is assuming the return type of it as int .作者可能忘记包含声明此原型的stdlib.h标头,因此编译器假定它的返回类型为int Now during static analysis of this code the compiler was warning about the unused return value of what it thinks to be a non- void function.现在,在此代码的静态分析期间,编译器警告它认为是非void函数的未使用返回值。 Such a warnings are usually silenced by adding the cast to void .这样的警告通常会通过将演员表添加到void来消除。

It would be a legacy thing!这将是一个遗产的事情!

Before there was a C standard, the free() function would have been (implicitly) of type int — because there was not yet reliably a type void for it to return.在有 C 标准之前, free()函数应该是(隐式) int类型——因为还没有可靠的void类型可以返回。 There was no value returned.没有返回值。

When the code was first modified to work with standard C compilers, it probably didn't include <stdlib.h> (because it didn't exist before the standard).当第一次修改代码以使用标准 C 编译器时,它可能不包含<stdlib.h> (因为它在标准之前不存在)。 Old code would write extern char *malloc();旧代码会写extern char *malloc(); (maybe without the extern ) for the allocation functions (similarly for calloc() and realloc() ), and didn't need to declare free() . (可能没有extern )用于分配函数(类似于calloc()realloc() ),并且不需要声明free() And the code would then cast the return value to the correct type — because that was necessary on at least some systems (including the one I learned C on).然后代码会将返回值转换为正确的类型——因为至少在某些系统上这是必要的(包括我学习 C 的系统)。

Sometime later, the (void) cast was added to tell the compiler (or, more likely, lint ) that "the return value from free() is deliberately ignored" to avoid a complaint.一段时间后,添加了(void)以告诉编译器(或者更有可能是lint )“故意忽略free()的返回值”以避免投诉。 But it would have been better to add <stdlib.h> and let its declaration extern void free(void *vp);但是最好添加<stdlib.h>并让它声明extern void free(void *vp); tell lint or the compiler that there was no value to ignore.告诉lint或编译器没有要忽略的值。

JFTR: Back in the mid-'80s, the ICL Perq was originally on a word-oriented architecture and the char * address for a memory location was a very different number from the 'anything_else pointer' to the same location. JFTR:早在 80 年代中期,ICL Perq 最初是在面向字的体系结构上,并且内存位置的char *地址与指向同一位置的“anything_else 指针”非常不同。 It was crucial to declare char *malloc() somehow;以某种方式声明char *malloc()至关重要; it was crucial to cast the result from it to any other pointer type.将结果从它转换为任何其他指针类型至关重要。 The cast actually changed the number used by the CPU.演员表实际上改变了 CPU 使用的数字。 (There was also much rejoicing when the main memory on our systems was upgraded from 1 MiB to 2 MiB — since the kernel used about 3/4 MiB, it meant that user programs could use 1 1/4 MiB before paging etc.) (当我们系统上的主内存从 1 MiB 升级到 2 MiB 时,也很高兴——因为内核使用了大约 3/4 MiB,这意味着用户程序可以在分页等之前使用 1 1/4 MiB。)

This cast is not needed.不需要这个演员表。 It probably wouldn't have been at the time as C had been standardized in the form of C89.当时可能不会,因为 C 已经以 C89 的形式标准化了。

If it had been, it would've been due to implicit declaration .如果是这样,那将是由于隐式声明 This usually meant that the person writing the code forgot to #include <stdlib.h> and a static analyzer was being used.这通常意味着编写代码的人忘记了#include <stdlib.h>并且正在使用静态分析器。 This is not the best workaround and a much better idea would've been to just #include <stdlib.h> instead.这不是最好的解决方法,一个更好的主意是改为#include <stdlib.h> Here's some wording from C89 about implicit declaration:以下是 C89 中关于隐式声明的一些措辞:

If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration如果函数调用中带括号的参数列表前面的表达式仅由一个标识符组成,并且没有对该标识符可见的声明,则该标识符被隐式声明,就像在包含函数调用的最里面的块中一样,声明

extern int identifier();

appeared.出现了。

But that's odd because they're not casting the result of malloc either, and malloc and free are in the same header file.但这很奇怪,因为它们也没有转换malloc的结果,并且mallocfree位于同一个头文件中。

It's also possible that this is just a mistake or some way to tell the reader that free returns no result.也有可能这只是一个错误或某种方式告诉读者free不会返回任何结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM