Linux – How does __USE_MISC referenced in glibc work

gccglibclinux

I'm just wondering how __USE_MISC works and where it's documented. I see a bunch of functions inside .h files require it and mention it. But it seems something is actively undefining it and I would like to know is doing that and how it makes that decision?

#define __USE_MISC 1
#include <stdio.h>

int main()
{
  printf("%d\n", __USE_MISC);
}

Returns

error: use of undeclared identifier '__USE_MISC'

That error goes away if I call it anything else, like _USE_MISC, or USE_MISC or foobar.

I've tried this with clang and gcc.

Best Answer

The __USE_* macros are not supposed to be defined and checked by the user, they're a mechanism to implement the feature selectors (_XOPEN_SOURCE, _GNU_SOURCE, etc) in glibc headers.

The whole mechanism is documented in a comment in the features.h header.

The features.h header is included from most standard headers (eg. from stdio.h) and the first thing it does is to undefine all the __USE_* macros, and then define them selectively depending on the _POSIX_C_SOURCE, _GNU_SOURCE, etc. macros defined by the user. Then the standard headers will ifdef things in and out based on those __USE_* macros.

One may wonder how to map back from a __USE_* macro to a _*_SOURCE macro that turns it on; for instance, one may want to compile their program with gcc -ansi, see that the psignal() function is only defined when the __USE_XOPEN2K8 is on, and wants to know what _*_SOURCE selector will get them that. Here is a table, generated with a script that had run gcc -ansi -E -dM "-D$source" -include features.h with different selectors:

__USE_ATFILE
        _ATFILE_SOURCE  _DEFAULT_SOURCE  _GNU_SOURCE
        _POSIX_C_SOURCE>=200809L  _XOPEN_SOURCE>=700
__USE_FILE_OFFSET64
        _FILE_OFFSET_BITS>=64
__USE_GNU
        _GNU_SOURCE
__USE_ISOC11
        _GNU_SOURCE  _ISOC11_SOURCE
__USE_ISOC95
        _DEFAULT_SOURCE  _GNU_SOURCE  _ISOC11_SOURCE  _ISOC99_SOURCE
        _POSIX_C_SOURCE>=200112L  _XOPEN_SOURCE>=600
__USE_ISOC99
        _DEFAULT_SOURCE  _GNU_SOURCE  _ISOC11_SOURCE  _ISOC99_SOURCE
        _POSIX_C_SOURCE>=200112L  _XOPEN_SOURCE>=600
__USE_LARGEFILE
        _GNU_SOURCE  _LARGEFILE_SOURCE  _XOPEN_SOURCE>=500
__USE_LARGEFILE64
        _GNU_SOURCE  _LARGEFILE64_SOURCE
__USE_MISC
        _DEFAULT_SOURCE  _GNU_SOURCE
__USE_POSIX
        _DEFAULT_SOURCE  _GNU_SOURCE  _POSIX_C_SOURCE  _POSIX_SOURCE
        _XOPEN_SOURCE>=500
__USE_POSIX199309
        _DEFAULT_SOURCE  _GNU_SOURCE  _POSIX_C_SOURCE>=199309L
        _XOPEN_SOURCE>=500
__USE_POSIX199506
        _DEFAULT_SOURCE  _GNU_SOURCE  _POSIX_C_SOURCE>=199506L
        _XOPEN_SOURCE>=500
__USE_POSIX2
        _DEFAULT_SOURCE  _GNU_SOURCE  _POSIX_C_SOURCE>=2
        _XOPEN_SOURCE>=500
__USE_POSIX_IMPLICITLY
        _DEFAULT_SOURCE  _XOPEN_SOURCE>=500
__USE_REENTRANT
        _REENTRANT  _THREAD_SAFE
__USE_UNIX98
        _GNU_SOURCE  _XOPEN_SOURCE>=500
__USE_XOPEN
        _GNU_SOURCE  _XOPEN_SOURCE>=500
__USE_XOPEN2K
        _DEFAULT_SOURCE  _GNU_SOURCE  _POSIX_C_SOURCE>=200112L
        _XOPEN_SOURCE>=600
__USE_XOPEN2K8
        _DEFAULT_SOURCE  _GNU_SOURCE  _POSIX_C_SOURCE>=200809L
        _XOPEN_SOURCE>=700
__USE_XOPEN2K8XSI
        _GNU_SOURCE  _XOPEN_SOURCE>=700
__USE_XOPEN2KXSI
        _GNU_SOURCE  _XOPEN_SOURCE>=600
__USE_XOPEN_EXTENDED
        _GNU_SOURCE  _XOPEN_SOURCE>=500
Related Question