feature test macros(_POSIX_C_SOURCE, _XOPEN_SOURCE, etc)

feature test macros(_POSIX_C_SOURCE, _XOPEN_SOURCE, etc)

Post by Vadim Grin » Thu, 10 Jun 2004 05:49:38


Hello,

The description of the problems I encountered is a little lengthy, so
I'll pose my question first, and the description will follow below :)

Question: Are there any issues to look out for when recompiling code
(either single-threaded or multi-threaded) with the following features
test macros enabled:
_POSIX_C_SOURCE, _XOPEN_SOURCE, and _XOPEN_SOURCE_EXTENDED ? Is there
any reason to use these if the code works w/o defining them [and doesn't
if they are defined :) ] ?

Here's my situation:

A number of places that talk about pthreads programming mention that the
code should be compiled with the macro _POSIX_C_SOURCE defined to be
equal to some value (199605L, if my memory serves me right).

I tried to rebuild my app with the macro defined on the compiler command
line, and as a result, certain bits of code no longer compiled. I
don't remember the exact errors right now, but it was something that
caused me to look in the system header files, and after some
experimenting, I got the code to compile again by defining two more
constants on the compiler command line (I saw the constants referenced
in the numerous #ifdefs in the headers).
At this point, my compiler's command line had the following added:

-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199605L

That had an unexpected side effect of changing a lot of the numbers
produced by the code to be, very consistently, 1 (one)... I became
suspicious and removed the "=1" part from the command line above, yielding

-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_POSIX_C_SOURCE=199605L

Rebuilding the code with the above definitions had the effect of causing
many of the numbers to become 270045908. Just like with the 1's, this
"result" was consistently reproducible.

Note that this problem happens even before the code gets to anything
thread-related, e.g., in the beginning of the prog, when a data file is
being read in and the data structures initialized; I've not yet traced
into the code deeply enough to isolate the first occurrence of the problem).

At this point, I figured I must be doing something wrong, and decided to
do some research; the only useful piece of information I found was the
description on the GNU libc page, but nothing there explained the wierd
side effects I was seeing, nor did I find anything else that was
relevant. Thus, I turn to this newsgroup and ask the question above.

Any information/suggestions would be most welcome.!

-Vadim

PS If it's relevant, this is happening on an SGI(IRIX 6.5) system.
 
 
 

feature test macros(_POSIX_C_SOURCE, _XOPEN_SOURCE, etc)

Post by David Bute » Fri, 11 Jun 2004 20:49:35

adim Grinshpun wrote:


On most modern systems, the "default" compilation environment is a mixture
of a wide range of standard functions and behaviors from a set of standards
as well as assorted proprietary functions and behaviors. Generally this
makes sense -- by default a program can take advantage of just about any
bit from a supported standard that doesn't conflict with another standard.

There are some cases where there are conflicts. One example that comes to
mind right now are that while POSIX up through POSIX 1003.1-1993 requires
that 'errno' be exactly 'extern int errno;' and specifies that a conforming
application need not include <errno.h> to use it, this assumption is NOT
compatible with ISO C, with POSIX 1003.1c-1995 or later, or with the Single
UNIX Specification V2 or later. So many systems stick with 'extern int
errno;' unless you've defined a compilation preprocessor symbol that
specifies a standard (e.g., _POSIX_C_SOURCE-199506L) that actually requires
something different. Another is that the traditional BSD signal handling
function prototype is fundamentally incompatible with the Single UNIX
Specification handler prototype; again, BSD-heritage systems will often use
the BSD prototype unless you've compiled with _XOPEN_SOURCE_EXTENDED, or
_XOPEN_SOURCE=500.

However, there's another aspect of standards that can be important to a lot
of "strictly conforming" portable applications. Standards generally specify
not only a list of symbols and semantics required by the standard; but also
something like the POSIX rule that there are no OTHER exported symbols in
headers defined by the standard. So, for example, since POSIX doesn't have
the symbol 'select', it's illegal for a conforming POSIX implementation to
define the symbol 'select' in any header defined by POSIX.

As a consequence, whereas a strict reading of the standard suggests that you
define _POSIX_C_SOURCE or _XOPEN_SOURCE to *enable* features of the
standard (and in some cases that's true), it's often more important to keep
in mind that defining the symbol must also *disable* features of the OS
that are not defined by the standard. For example, when you define
_POSIX_C_SOURCE=199506L to build with thread support (and a proper errno
definition), your code generally will not have a prototype for select() in
scope -- because that would be illegal.

This is most likely what you're experiencing -- you've limited the
compilation environment to exclude something your program needs.

Technically, by the way, defining _XOPEN_SOURCE_EXTENDED and
_POSIX_C_SOURCE=199506L is seriously bad. (Which isn't to say it might not
work some places.) That's because _XOPEN_SOURCE_EXTENDED is based on POSIX
1003.1-1990, which, as I said at the beginning, explicitly FORBIDS a
definition of errno that's compatible with threads. Which of the symbols
will take precedence in this case is undefined by any standard, of course,
and you'd better review everything to be really sure that what you've built
is CORRECT. Defining both _XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED has
similar problems, since _XOPEN_SOURCE with no value means strict XPG 4
while _XOPEN_SOURCE_EXTENDED means strict XPG 4.2 -- they have mutually
incompatible requirements, which is why the latter symbol was added.

Most implementations have some symbol (which may or may not be well
documented) that overrides the namespace restricti