LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-12-2010, 05:08 PM   #1
posixculprit
Member
 
Registered: May 2010
Posts: 136

Rep: Reputation: 42
Defining _POSIX_C_SOURCE in applications desired to be POSIX conformant


Hello. I am writing an application ( C99 ) and I desire to make it POSIX 2008 compliant for portability reasons.

According to [1] http://www.opengroup.org/onlinepubs/...l#tag_02_02_01 :
Quote:
8. For the C programming language, shall define _POSIX_C_SOURCE to be 200809L before any header is included
According to [2] http://www.gnu.org/s/libc/manual/htm...st-Macros.html :
Quote:
You should define these macros by using ‘#define’ preprocessor directives at the top of your source code files. These directives must come before any #include of a system header file. It is best to make them the very first thing in the file, preceded only by comments. You could also use the ‘-D’ option to GCC, but it's better if you make the source files indicate their own meaning in a self-contained way.
From the two paragraphs quoted above, I gather that each of my C source files ( *.c ) should begin with the following definition:

Code:
#define _POSIX_C_SOURCE 200809L
However, I am unsure what to do in the case of C header files. Assume a "library" written in C99 which we desire to make POSIX 2008 conformant. Assume the library contains (among others) the following files:

1. alpha_interface.h:

Code:
#ifndef ALPHA_INTERFACE_H
#define ALPHA_INTERFACE_H

#include <sys/socket.h>
#include <sys/types.h>

ssize_t alpha(const struct sockaddr *);

#endif
2. alpha_implementation.c:

Code:
#include <sys/socket.h>
#include <sys/types.h>

#include "alpha_interface.h"

ssize_t alpha(const struct sockaddr *s)
{
       // implementation
}
3. beta_interface.h:

Code:
#ifndef BETA_INTERFACE_H
#define BETA_INTERFACE_H

#include <sys/socket.h>
#include <sys/types.h>

ssize_t beta(const struct sockaddr *, const struct sockaddr *);

#endif
4. beta_implementation.c:

Code:
#include <sys/socket.h>
#include <sys/types.h>

#include "beta_implementation.h"

ssize_t beta(const struct sockaddr *s1, const struct sockaddr *s2)
{
        // implementation
}
Note: the previous are only meant for clarification, they are not simplified versions of files within my program.

According to [1] and [2] all four files should define _POSIX_C_SOURCE before including <sys/socket.h> and <sys/types.h>. Now also assume we have a program which is to use the above described library, as such:

Code:
#include <sys/socket.h>
#include <unistd.h>

#include "alpha_interface.h"
#include "beta_interface.h"

int main(int argc, char *argv)
{
        // parse command line options using getopt()
        // use alpha()
        // use beta()
}
Since the program includes <sys/socket.h> and <unistd.h> it also has to define _POSIX_C_SOURCE.

The above scenario introduces the following programs:

- Redefinition of _POSIX_C_SOURCE. This can be avoided if, for example, "somewhere" in alpha_interface.h and beta_interface.h the following sequence occures: "#undef _POSIX_C_SOURCE". This could occur either after the last #include directive, or, for symmetry purposes, at the very end of the file. The alpha_interface.h file could end up looking as such:

Code:
#define _POSIX_C_SOURCE 200809L

#ifndef ALPHA_INTERFACE_H
#define ALPHA_INTERFACE_H

#include <sys/socket.h>
#include <sys/types.h>

ssize_t alpha(const struct sockaddr *);

#endif

#undef _POSIX_C_SOURCE
This looks fairly inelegant to me, I'm wondering if there is a better way.

- Changing to a new version of the POSIX standard would require modification of every source file.

I'm curious as to the recommended/usual solutions for these problems, or, if I'm doing something wrong, I would very much appreciate to be told what that something is.

Last edited by posixculprit; 05-12-2010 at 05:12 PM.
 
Old 05-13-2010, 05:06 AM   #2
posixculprit
Member
 
Registered: May 2010
Posts: 136

Original Poster
Rep: Reputation: 42
In the case of getopt(), things are really unclear to me. According to the getopt(3) manpage on my Linux system, _POSIX_C_SOURCE >= 2 or _XOPEN_SOURCE are required to be defined. This is most likely a result of the getopt_long and getopt_long_only extensions which are to be made visible by defining _GNU_SOURCE. Alternatively, at the very least on FreeBSD and NetBSD, neither _POSIX_C_SOURCE nor _XOPEN_SOURCE are required. Indeed, it would seem that in order to be portable, a program using getopt -must- #define _POSIX_C_SOURCE or _XOPEN_SOURCE.

However, the first example from http://www.opengroup.org/onlinepubs/...#tag_16_206_06 doesn't make use of _POSIX_C_SOURCE nor _XOPEN_SOURCE at all.
 
Old 06-02-2010, 03:32 PM   #3
posixculprit
Member
 
Registered: May 2010
Posts: 136

Original Poster
Rep: Reputation: 42
In the event that someone (else) will find this input helpful, here is a short and dirty follow-up.

In the case of header files, it is not a good idea to begin the file with something such as:

Code:
#define _POSIX_C_SOURCE 200809L
because this would make _POSIX_C_SOURCE be defined in all the source files which happen to #include the given header file. For example:

Code:
// alpha.h
#define _POSIX_C_SOURCE 200809L
#ifndef ALPHA_H
#define ALPHA_H
void alpha(void);
#endif
Code:
// omega.c
<...>
#include "alpha.h"
// !!! _POSIX_C_SOURCE is defined at this point, which might be not obvious, and not what the developer of omega.c expects/wants/needs. This could even lead to difficult to debug errors !!!
Problems might also occur if a source file defines _POSIX_C_SOURCE before including alpha.h. This:

Code:
#undef  _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
takes care of the problem but introduces a new one:

Code:
#define _POSIX_C_SOURCE 42
#include "alpha.h"
// at this point, _POSIX_C_SOURCE is defined to be 200809L, which might not be obvious nor, indeed, needed/desired behaviour
In any case, a fairly ugly solution follows:

Code:
// alpha.h
#ifdef  _POSIX_C_SOURCE
#define _POSIX_C_SOURCE_BACKUP _POSIX_C_SOURCE
#undef  _POSIX_C_SOURCE
#endif

#define _POSIX_C_SOURCE 200809L

#ifndef ALPHA_H
#define ALPHA_H
// ...
// ...
#endif

#undef  _POSIX_C_SOURCE

#ifdef  _POSIX_C_SOURCE_BACKUP
#define _POSIX_C_SOURCE _POSIX_C_SOURCE_BACKUP
#undef  _POSIX_C_SOURCE_BACKUP
#endif

Last edited by posixculprit; 06-02-2010 at 03:34 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how to set the right charset (or desired) amimusa Debian 1 04-05-2007 03:07 AM
Desired delay in potfix hotrodowner Linux - Software 2 03-11-2005 05:37 AM
SSH and desired interface stakhous Linux - Networking 1 02-05-2005 01:10 AM
Defining terms Kurt M. Weber General 1 10-25-2003 07:25 PM
Defining the Slices desbyleo Solaris / OpenSolaris 10 05-07-2003 09:18 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:51 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration