为什么c库和语言先定义_name,然后typedef或pound定义_name? [英] Why do the c libraries and language define _name and then typedef or pound define _name 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 #include
d; 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屋!