glibc - #define void

问题描述 投票:0回答:4

我开始研究 glibc (GNU Libc) 了解它是如何写的。在

malloc.c
中,我发现了一段代码如下:

#ifndef void
#define void        void
#endif

有人可以向我解释一下这是什么意思吗?

void
不是总是被定义的吗?

谢谢

c glibc libc
4个回答
10
投票

查看git历史记录,是这样的:

/*
  Void_t* is the pointer type that malloc should say it returns
*/

#ifndef Void_t
#if (__STD_C || defined(WIN32))
#define Void_t      void
#else
#define Void_t      char
#endif
#endif /*Void_t*/

这是历史 [C] 的解决方法,它没有

void
并且
malloc()
返回
char *
而不是
void
。该代码于 2011 年被 Ulrich Drepper 删除。提交似乎不是由脚本或任何自动生成的,因此他一定有某种意图来定义它。

提交消息没有提及任何关于

void
:

简化 malloc 代码

删除各种未使用的配置选项和死代码。


9
投票

我不确定

#define void void
的原因是什么,但我的猜测如下:

正如

Yasushi Shoji 提到的

malloc.c 并不总是 C 中的关键字。当它被引入/标准化时,一种常见的解决方法是能够使用新的

void
关键字与不支持它的编译器来编译代码是将
void
定义为宏,例如:

void

宏定义可以使用编译器命令行而不是通过标头来完成,这样就不需要确保所有翻译单元都包含定义宏的标头。 

但是,迁移到 new 关键字的程序员使用如下代码序列也可能很常见:

#define void int /* or maybe #define void char */

例如,您将看到以下代码:

#ifndef void #define void int #endif

http://buildbot.zope.org/Squid-2.4STABLE6%2B/include/snmp_impl.h?annotate=1.1.1.1&cvsroot=Zope.org

所以,我的猜测是,

/* * This is a fairly bogus thing to do, but there seems to be no better way for * compilers that don't understand void pointers. */ #ifndef void #define void char #endif

中的

#define void void
只是一种防止其包含的标头中可能存在的任何此类序列重新定义
malloc.c
的方法,但仍然允许它之前已被“全局”定义(在
void
之前的
malloc.c
中只有注释)以防在不支持
#define void void
的配置上编译它。换句话说,如果在开始编译
void
之前未将
void
全局定义为宏,则没有理由在稍后的编译中将某些内容定义为其他内容。
    


4
投票
malloc.c

是 C 中的关键字,但关键字并未定义为预处理器符号。您引用的代码确保它也被定义为预处理器符号。


我不知道为什么这是必要的。


0
投票
void

可能总是有意义的,但我会说 void

isn't
通常 voidd。我不知道
确切
发生了什么,但这段代码运行的结果是,如果稍后有人说#define,那就是真的。换句话说,通过这段代码,它只会从
#ifdef void
变为
#define
一次。
    

© www.soinside.com 2019 - 2024. All rights reserved.