What is __XSI_VISIBLE?

969 views Asked by At

I was working on a C/C++ project for an embedded system that uses gcc-arm-none-eabi-8-2019-q3-update as a compiler.

I added the use of the strptime function of time.h but initially it was undefined and I found in the compiler inclusions:

#if __XSI_VISIBLE
 ...strptime...
#endif

So, I solved the problem with:

#undef __XSI_VISIBLE
#define __XSI_VISIBLE 1
#include <time.h>
#undef __XSI_VISIBLE
#define __XSI_VISIBLE 0

Now it works BUT:

  • What have I done?
  • What is __XSI_VISIBLE?
  • What is it for?
  • Why does this compiler keep it by default at 0?
2

There are 2 answers

2
Jens On BEST ANSWER

From https://pubs.opengroup.org/onlinepubs/9699919799/:

The X/Open System Interfaces (XSI) option is the core application programming interface for C and sh programming for systems conforming to the Single UNIX Specification. This is a superset of the mandatory requirements for conformance to POSIX.1-2017.

The __XSI_VISIBLE macro makes visible extensions to "vanilla" POSIX interfaces, which otherwise would be forbidden to be in the name space. Remember that C language standards like ISO C and POSIX permit the application to define all non-standard identifiers (in ISO C and "vanilla" POSIX, strptime is not reserved, you can write a function with that name and have it not interfere). By defining so-called feature test macros you extend the set of standard identifiers and reduce those available to define by the application programmer.

Your compiler keeps it at 0 because the implementation vendor chose that it is the application programmer's job to enable XSI when s/he wants it. Application programmers do this by defining the desired feature test macros before header inclusion, e.g. with

#define _POSIX_SOURCE
#define __XSI_VISIBLE 1
#include <time.h>

or pass -D__XSI_VISIBLE=1 to the compiler.

0
Nick On

The correct defs to use are -D_XOPEN_SOURCE=1 and -D_GNU_SOURCE=1. These are used to conditionally define __XSI_VISIBLE and __GNU_VISIBLE respectively in <sys/features.h>. Defining __XSI_VISIBLE and __GNU_VISIBLE will not always work because they are overridden in <sys/features.h>.