Why do the c libraries and language define _name and then typedef or pound define _name name?

时光总嘲笑我的痴心妄想 提交于 2020-06-26 04:14:14

问题


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

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?

Another example in stdio.h:

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

And later:

#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?


回答1:


It's all about namespace management.

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).

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

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.

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 is just wrong. Gtk isn't a libc implementation, and so it has no business using those reserved names.



来源:https://stackoverflow.com/questions/55152124/why-do-the-c-libraries-and-language-define-name-and-then-typedef-or-pound-defin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!