Почему библиотеки и язык c определяют _typename, а затем typedef или pound определяют _typename typename? - PullRequest
3 голосов
/ 14 марта 2019

Кажется, что в библиотеках и языке Си много бесполезных имен типов. Например, 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 Ответ

2 голосов
/ 14 марта 2019

Все дело в управлении пространством имен.

Имена с префиксом в виде двух символов подчеркивания или подчеркивания и заглавной буквы зарезервированы для реализации. Реализация может выставлять их практически без разбора (ну, на самом деле, не очень понятно, какие зарезервированные имена принадлежат компиляторам, а какие реализациям 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 (вызвано правильными макросами тестирования функции ) блок удовлетворен.

Когда они используют префиксные формы (определенные во внутреннем <bits/waitstatus.h>), <sys/wait.h> может затем использовать те же самые (идентично переопределенные макросы не генерируют предупреждения), и все работает, даже когда они оба #include д; и ни один заголовок не предоставляет больше незарезервированных имен, чем требуется действующими стандартами (используемые стандарты зависят от макросов тестирования функции , с которыми вы компилируете).

ГТК просто неправильно. Gtk не является реализацией libc и поэтому не имеет права использовать эти зарезервированные имена.

...