为什么c库和语言先定义_name,然后typedef或pound定义_name? [英] Why do the c libraries and language define _name and then typedef or pound define _name name?

查看:46
本文介绍了为什么c库和语言先定义_name,然后typedef或pound定义_name?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎C库和语言具有许多无用的类型名称.例如,C具有内置类型 _Bool ,并且在 stdbool.h 中有一个宏, #define bool _Bool .为什么C只是内置了 bool 而不是 _Bool ?我在 stdio.h stdlib.h 中找到了更多示例.像这样:

It seems that the C libraries and language has a lot of useless type names. For example, C has a built in type _Bool and there is a macro in stdbool.h, #define bool _Bool. Why didn't C just have bool built in instead of _Bool? I found more examples in stdio.h and stdlib.h. Like this:

# 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)开头呢?

My question is why bother declaring a function __FUNCTIONNAME (arg) and then #define FUNCTIONNAME(arg) __FUNCTIONNAME(arg)? Why not just declare FUNCTIONNAME(arg) to start with?

stdio.h 中的另一个示例:

extern FILE *__stdinp;
extern FILE *__stdoutp;
extern FILE *__stderrp;

后来:

#define stdin __stdinp
#define stdout __stdoutp
#define stderr __stderrp

很喜欢,为什么?仅定义它们然后像这样声明它们有什么问题?

Like seriously, why? What is wrong with just defining them then declaring them like this:

extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;

为什么他们不只是声明没有下划线的函数,然后又不需要这些宏?

Why didn't they just declare the functions without the underscores and then have no need for these macros?

推荐答案

这全都与名称空间管理有关.

It's all about namespace management.

以两个下划线或下划线和大写字母为前缀的名称保留实现.一个实现实际上可能会不加选择地暴露它们(嗯,实际上不是很清楚哪些保留名称属于编译器,哪些保留名称属于libc实现).

Names prefixed with two underscores or an underscore and an upper case letter are implementation-reserved. An implementation may expose them virtually indiscriminately (well, it's not really very clear which reserved names belong to compilers and which to libc implementations).

诸如 WIFCONTINUED 之类的名称属于用户(在POSIX下为< sys/wait.h> )和 stdlib.h 不应在POSIX下包含它们.

Names like WIFCONTINUED, on the other hand, belong to the user (and <sys/wait.h> under POSIX), and stdlib.h shouldn't contain them under POSIX.

GLIBC仅在有条件的情况下才从 stdlib.h 中公开它们:

GLIBC exposes them from stdlib.h only conditionally:

#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.  */

并且 #include < sys/wait.h> 不包括它们,可能是因为< sys/wait.h> 即使此 #if 的条件(可能由正确的

and it's not including them by #including <sys/wait.h> probably because <sys/wait.h> likely has other stuff that shouldn't be included even if the condition for this #if (triggered by the right feature test macros ) block is satisfied.

当使用前缀形式(在内部< bits/waitstatus.h> 中定义)时,< sys/wait.h> 然后可以重用相同的对象(完全重新定义的宏不会生成警告),即使它们都被 #include d都可以正常工作;并且没有标头会显示比有效标准所要求的更多的非保留名称(所使用的标准取决于

When they use the prefixed forms (defined in the internal <bits/waitstatus.h>), <sys/wait.h> can then reuse the same ones (identically redefined macros don't generate warnings) and everything works even when they're both #included; and no header exposes more non-reserved names than required by the standards in force (the standards in use depend on the feature test macros with which you compile).

GTK是错误的.Gtk并不是libc的实现,因此使用这些保留的名称就没事了.

Gtk is just wrong. Gtk isn't a libc implementation, and so it has no business using those reserved names.

这篇关于为什么c库和语言先定义_name,然后typedef或pound定义_name?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆