看来 C 库和语言有很多无用的类型名称。例如,C 有一个内置类型_Bool
并且有一个宏stdbool.h
, #define bool _Bool
。为什么 C 没有bool
内置而不是_Bool
?我发现了更多的例子stdio.h
and stdlib.h
。像这样:
# define WEXITSTATUS(status) __WEXITSTATUS (status)
# define WTERMSIG(status) __WTERMSIG (status)
# define WSTOPSIG(status) __WSTOPSIG (status)
# define WIFEXITED(status) __WIFEXITED (status)
# define WIFSIGNALED(status) __WIFSIGNALED (status)
# define WIFSTOPPED(status) __WIFSTOPPED (status)
# ifdef __WIFCONTINUED
# define WIFCONTINUED(status) __WIFCONTINUED (status)
# endif
我的问题是为什么要声明一个函数__FUNCTIONNAME (arg)
进而#define FUNCTIONNAME(arg) __FUNCTIONNAME(arg)
?为什么不直接声明FUNCTIONNAME(arg)
首先?
另一个例子在stdio.h
:
extern FILE *__stdinp;
extern FILE *__stdoutp;
extern FILE *__stderrp;
然后:
#define stdin __stdinp
#define stdout __stdoutp
#define stderr __stderrp
认真地说,为什么?仅仅定义它们然后像这样声明它们有什么问题:
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
为什么他们不直接声明不带下划线的函数,然后就不需要这些宏了?
这都是关于命名空间管理的。
以两个下划线或一个下划线和一个大写字母为前缀的名称是实现保留的。实现可能会几乎不加区别地公开它们(好吧,并不是很清楚哪些保留名称属于编译器,哪些属于 libc 实现)。
名字像WIFCONTINUED
另一方面,属于用户(并且<sys/wait.h>
在 POSIX 下),以及stdlib.h
在 POSIX 下不应包含它们。
GLIBC 将它们暴露于stdlib.h
仅有条件地:
#if (defined __USE_XOPEN || defined __USE_XOPEN2K8) && !defined _SYS_WAIT_H
/* XPG requires a few symbols from <sys/wait.h> being defined. */
# include <bits/waitflags.h>
# include <bits/waitstatus.h>
/* Define the macros <sys/wait.h> also would define this way. */
# define WEXITSTATUS(status) __WEXITSTATUS (status)
# define WTERMSIG(status) __WTERMSIG (status)
# define WSTOPSIG(status) __WSTOPSIG (status)
# define WIFEXITED(status) __WIFEXITED (status)
# define WIFSIGNALED(status) __WIFSIGNALED (status)
# define WIFSTOPPED(status) __WIFSTOPPED (status)
# ifdef __WIFCONTINUED
# define WIFCONTINUED(status) __WIFCONTINUED (status)
# endif
#endif /* X/Open or XPG7 and <sys/wait.h> not included. */
并且它不包括它们#including
<sys/wait.h>
可能是因为<sys/wait.h>
可能有其他不应该包含的东西,即使这个条件#if
(由右侧触发功能测试宏 http://man7.org/linux/man-pages/man7/feature_test_macros.7.html)块满足。
当他们使用前缀形式(在内部定义<bits/waitstatus.h>
), <sys/wait.h>
然后可以重用相同的宏(同样重新定义的宏不会生成警告),即使它们都是#include
d;并且没有标头公开比现行标准要求更多的非保留名称(使用的标准取决于功能测试宏 http://man7.org/linux/man-pages/man7/feature_test_macros.7.html你用它来编译)。
Gtk 是错误的。 Gtk 不是 libc 实现,因此它没有必要使用这些保留名称。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)