Search code examples
clinuxposixconditional-compilation

Cross-platform compatibility of dprintf


Linux has this nice function dprintf:

The functions dprintf() and vdprintf() (as found in the glibc2 library) are exact analogues of fprintf() and vfprintf(), except that they output to a file descriptor fd instead of to a given stream.

however as that same source points out:

These functions are GNU extensions, not in C or POSIX. Clearly, the names were badly chosen. Many systems (like MacOS) have incompatible functions called dprintf(), usually some debugging version of printf(), perhaps with a prototype like

void dprintf (int level, const char *format, ...);

where the first parameter is a debugging level (and output is to stderr). Moreover, dprintf() (or DPRINTF) is also a popular macro name for a debugging printf. So, probably, it is better to avoid this function in programs intended to be portable.

My question

How can I make a setup that will safely call the dprintf that I want, if it exists, or fail to compile with some reasonably sane error message if that function doesn't exist? I guess I'd do something like this:

#ifdef SOMETHING
    #define Dprintf dprintf
#else
    #error "no dprintf"
#endif

but I don't know what SOMETHING should be. I guess I could restrict it to just Linux but could I make it looser?


Solution

  • Looks like dprintf() is actually in POSIX.1-2008 (with the semantics you want), so you can do this:

    #if !defined(__GLIBC__) && _POSIX_C_SOURCE < 200809
    #error "dprintf may not exist, or may be wrong"
    #endif
    

    __GLIBC__ is defined if you're using a gnu build system. This is probably as safe as you can be without writing a small test program.