Search code examples
cgccposix

How to test if strdup() is available?


I'm using this:

#if !defined(_SVID_SOURCE) || !defined(_BSD_SOURCE) || _XOPEN_SOURCE < 500 || !(_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) \
|| _POSIX_C_SOURCE < 200809L
char * strdup(const char *s)
{
  char *buffer = malloc(strlen(s) + 1);

  if(buffer != NULL)
    strcpy(buffer, s);

  return buffer;
}
#endif

But is there the possibility to get a redeclaration error? Maybe into some gcc version or gcc-like compiler? I want to make it compatible with versions (standards) where there is no strdup(), -ansi, for example.

Also, how can I make it more portable?


Solution

  • This is absolutely the wrong use of feature test macros. Feature test macros are not defined by the implementation to tell the application what's available; they're defined by the application to request that the implementation provide conformance to (a particular version of) a particular standard.

    The macros you should be using to test for a what the implementation supports are in unistd.h:

    • _POSIX_VERSION - version of POSIX supported. 200809L is latest.
    • _XOPEN_VERSION - version of X/Open Portability Guide, now called the "XSI" option of POSIX. Latest is 700 (from SUSv4). 600 (SUSv3) is common. 500 (SUSv2) is badly outdated.
    • _POSIX_THREADS - version of pthreads (should be the same as _POSIX_VERSION; mandatory since POSIX 2008)
    • ...