为什么c库和语言先定义_typename,然后再用typedef或pound定义_typename typename?

时间:2019-03-13 22:29:48

标签: c macros double-underscore underscores

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;

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

1 个答案:

答案 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的实现,因此使用这些保留的名称就没有任何业务。