C库和语言似乎有很多无用的类型名称。例如,C具有内置类型_Bool
,并且stdbool.h
,#define bool _Bool
中有一个宏。为什么C只是内置bool
而不是_Bool
?我在gtk和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
#endif
gtk中的另一个示例:
typedef struct _GtkContainer GtkContainer;
typedef struct _GtkContainerPrivate GtkContainerPrivate;
typedef struct _GtkContainerClass GtkContainerClass;
struct _GtkContainer
{
GtkWidget widget;
/*< private >*/
GtkContainerPrivate *priv;
};
为什么没有这样的东西:
typedef struct
{
GtkWidget widget;
/*< private >*/
GtkContainerPrivate *priv;
} GtkContainer;
为什么他们不只是声明没有下划线的函数,然后又不需要这些宏?
答案 0 :(得分:2)
所有与名称空间管理有关。
以两个下划线或下划线和大写字母为前缀的名称将保留实现。一个实现可能几乎不加选择地暴露它们(嗯,实际上不是很清楚哪些保留名称属于编译器,哪些保留名称属于libc实现)。
另一方面,WIFCONTINUED
之类的名称属于用户(在POSIX下为<sys/wait.h>
),而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
的条件(由右边的feature test macros)块已满足。
当它们使用前缀形式(在内部<bits/waitstatus.h>
中定义)时,<sys/wait.h>
然后可以重用相同的形式(完全相同的重新定义的宏不会生成警告),并且即使它们是两者#include
d;并且没有标头会公开比有效标准所要求的更多的非保留名称(所使用的标准取决于您编译时所使用的feature test macros)。
GTK是错误的。 Gtk不是libc的实现,因此使用这些保留的名称就没有任何业务。