详细介绍 glibc 特性宏的使用

2020-10-23 language c/cpp

GNU C Library 也就是 glibc 库,是目前 Linux 上最为基本的 C 语言库,不过其实现的不只是标准的 C 定义,还包括了其它的一些标准协议,不同场景下用户可以使用不同的接口。

这些特性的开启都是通过宏来实现的,这里详细介绍其使用方式。

简介

在 glibc 中,实现了很多标准,其中部分规范有:

  • ISO C The international standard for the C programming language.
  • POSIX The ISO/IEC ArrayArray45 (aka IEEE 1003) standards for operating systems.
  • Berkeley Unix BSD and SunOS.
  • SVID The System V Interface Description.
  • XPG The X/Open Portability Guide.

如果只需要使用 ISO C 功能,那么在编译时可以使用 -ansi 选项,glibc 实现了全部的 ISO C 功能,而 POSIX 是 ISO C 的超集,还包括了文件系统、终端设备、进程相关的函数。

Berkeley Unix 实现了前两者多数功能,源于 4.2 BSD、4.3 BSD、4.4 BSD Unix 系统 (一般称为 Berkeley Unix) 以及 SunOS (基于 4.2 BSD 但是又实现了 System V 的部分功能),额外包括了符号链接、select IO 复用函数、BSD 信号函数、Socket 接口。

SVID 的全称是 System V Interface Description 描述 AT&T Unix System V operating system 的一份文档,某种意义上是 POSIX 的超集,但是没有已有的 Unix 实现了其全部功能,glibc 也仅仅实现了其部分功能,额外实现的功能包括 IPC、共享内存、hsearch、drand48、fmtmsg 以及一些其它的数学函数。

最后的 The X/Open Portability Guide, XPG 描述了什么样的系统满足类 Unix 系统的基本需要,glibc 服从该要求。

使用

在编写程序时,为了使用上述实现的功能,需要定义对应的宏,例如要使用 POSIX 的接口,需要应定义 _POSIX_SOURCE ,类似的还有 _BSD_SOURCE_SVID_SOURCE_XOPEN_SOURCE 等。

如前所述,可以通过 -ansi 参数仅使用 ISO C 内的功能,其它特性使用时可以在所有的头文件前通过 #define _BSD_SOURCE 定义宏,或者使用 gcc 编译时通过 -D_BSD_SOURCE 参数定义一个宏。

其它

_DEFAULT_SOURCE

在比较新的版本中 (严格来说是大于 2.10 版本),如果继续使用 _BSD_SOURCE 或者 _SVID_SOURCE 会有如下的报错 warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE"

也就是说,在新版本中建议使用 _DEFAULT_SOURCE 而不是 _BSD_SOURCE 宏,不过这样会有一个问题,同一份代码,在新旧 glibc 版本中如何进行适配。

目前来看,没有找到太好的办法,需要在 CMake 类似的工具里进行判断。