[cs631apue] [CS631] #define _XOPEN_SOURCE 500

Jan Schaumann jschauma at stevens.edu
Thu Nov 8 22:25:36 EST 2012


tparisi <tparisi at stevens.edu> wrote:

> I am having trouble getting pread() to work.  I know from the man page  
> that I am to include unistd.h and add #define _XOPEN_SOURCE 500 to the  
> file but I am getting this error when I add the #define line:  
> /usr/include/bsd/stdlib.h:47: error: expected ?)? before ?*? token.

Sorry for the late reply.

Different functions were introduced on different systems/standards at
different times.  These preprocessor directives (or command-line flags
to the compiler) can specify which standard one wishes to conform with.

It is generally advisable to be as conservative as possible so as to
remain backwards compatible or cross-platform compatible.  Unfortunately
some libraries may not work well with certain definitions and/or rely on
specific features to be enabled.

The _XOPEN_SOURCE macro can be defined to ensure inclusion of various
POSIX related functions.  You can find out more about what kinds of
macros you can use in /usr/include/features.h -- there, _XOPEN_SOURCE is
described:

_XOPEN_SOURCE        Includes POSIX and XPG things.  Set to 500 if
                     Single Unix conformance is wanted, to 600 for the
                     sixth revision, to 700 for the seventh revision.

Alright, so far so good -- enabling _XOPEN_SOURCE gives us basic SUS /
POSIX compatibility.  But then it triggers the error you noted:

/usr/include/bsd/stdlib.h:47: error: expected ')' before '*' token

Looking at line 47 of that file, we see:

void arc4random_addrandom(u_char *dat, int datlen);

The word before the '*' token is 'u_char', an abstract data type.  This
datatype needs to be defined to be usable, but apparently it isn't.
System types are generally defined in /usr/include/sys/types.h, where we
find 'u_char' to be conditionally defined based on __USE_BSD being
defined:

#ifdef  __USE_BSD
# ifndef __u_char_defined
typedef __u_char u_char;
[...]
#  define __u_char_defined
# endif
#endif

Now back in /usr/include/features.h, we can find __USE_BSD being
defined...

#ifdef  _BSD_SOURCE
# define __USE_BSD      1
#endif

...only if _BSD_SOURCE is defined.

So if you define *both* _BSD_SOURCE and _XOPEN_SOURCE, then you should
be able to use both pread(2) as well as any functions from the bsd
compatibility library.

#define _BSD_SOURCE
#define _XOPEN_SOURCE 500
#include <unistd.h>
#include <bsd/stdlib.h>


We will discuss preprocessor directives and how they are expanded in a
future class in more detail.

-Jan


More information about the cs631apue mailing list