Thread: Use of #ifdef for portability - a specific case

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    98

    Use of #ifdef for portability - a specific case

    In Solaris, the protoptype of psignal() is in siginfo.h. However, under Linux and Mac OS X, the protoptype of psignal() is in signal.h; siginfo.h does not exist. Some advocate writing 2 different .c files. Let's say I do not want to do that for such a minor discrepancy. How do I write a C program that can run on all 3 operating systems, by using #ifdef for example? That is, how can I do something like:
    Code:
    #ifdef SOLARIS
    #  include <siginfo.h>
    #else
    #  include <signal.h>
    #endif
    int main ()
    { ...
       ... psignal() ...
       ...
    }
    Thanks.
    Last edited by hzmonte; 11-03-2005 at 02:46 AM.

  2. #2
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    Long time no C. I need to learn the language again.
    Help a man when he is in trouble and he will remember you when he is in trouble again.
    You learn in life when you lose.
    Complex problems have simple, easy to understand wrong answers.
    "A ship in the harbour is safe, but that's not what ships are built
    for"

  3. #3
    Registered User
    Join Date
    Jul 2005
    Posts
    98
    Thanks. I found another article Notes on Writing Portable Programs in C (http://www.literateprogramming.com/portableC.pdf) that is also good. It gives an example:
    #ifdef SYSV
    # include <fcntl.h>
    #else
    # include <sys/file.h>
    #endif
    Now my first uestion is: How do I find out whether a particular constant, e.g. SYSV, is defined in my OS? Barring reading the manual, is there a commonly available OS command that lists all the constants that are defined? And if an OS defines SYSV, does it absolutely mean that <fcntl.h> exists, for example? I mean, is it possible that a "SYSV-based" operating system does not have <fcntl.h>? In Spencer and Collyer's "#ifdef Considered Harmful" (1992), they argue that "the UNIX world is NOT cleanly split into System V and 4BSD camps, particularly with the advent of SVR4. Hybrid UNIXes are the rule, not the exception, nowadys." Therefore, one should not base the test on generalizations about an OS type (e.g. all SYSV systems have <fcntl.h>) . However, unfortunately, they do not offer an alternative way to handle a case like the above, without using #ifdef. Any suggestion?

  4. #4
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    symbols are usually compiler dependent, not os dependent. one compiler may define SYSV while another compiler may or may not. So if you always use the same compiler on all operating systems you should be ok.

    It would be impossible to get a list of all defined constants because programs are allowed to define their own and undefine those that may have been previously defined in header files.

  5. #5
    Registered User
    Join Date
    Jul 2005
    Posts
    98
    Do you mean that a compiler for a System V-based OS would define SYSV, for example? GCC does not seem to define any OS-specific constants - see http://gcc.gnu.org/onlinedocs/gcc-3....ed-Macros.html.
    "So if you always use the same compiler on all operating systems you should be ok. " What do you mean? Assumed that I always use GCC on all OSes, I still need to know whether the OS I am compiling the code on has fcntl.h or sys/file.h, say for example.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    Quote Originally Posted by hzmonte
    Do you mean that a compiler for a System V-based OS would define SYSV, for example? GCC does not seem to define any OS-specific constants - see http://gcc.gnu.org/onlinedocs/gcc-3....ed-Macros.html.
    "So if you always use the same compiler on all operating systems you should be ok. " What do you mean? Assumed that I always use GCC on all OSes, I still need to know whether the OS I am compiling the code on has fcntl.h or sys/file.h, say for example.
    all those constants are specific to a compiler -- there is no standard set of constants. If you use g++ or gcc on all platforms then I think the constants will normally be consistant from one platform to another. But don't expect any of the constants defined by gcc or g++ to be used by the cc compiler on AIX Unix or by any other compiler.

    This lack of consistency among compilers makes writing cross-platform and cross-compiler programs very problematic. Just download any open source library that has been ported to different platforms and you will probably find the source code littered with conditional compile preprocessor statements. www.DataReel.com has a good example that supports quite a few compilers on both *nix and MS-Windows.

    The link that Dave posted previously contains many of the most commonly used macros, but it is by far not complete. Each of the compilers have many more predefined macros that are not listed.
    Last edited by Ancient Dragon; 11-03-2005 at 09:37 PM.

  8. #8
    Registered User
    Join Date
    Jul 2005
    Posts
    98

    Many thanks, Ancient Dragon and Dave_Sinkula

    I found that with GCC, the command "touch foo.h; cpp -dM foo.h", assumed foo.h does not exist, prints out all GCC's predefined macros. And in Solaris 9, a macro named SVR4 is predefined with a value of 1. In GNU/Linux 2.4 and Mac OS X (the Darwin kernel), no such macro is defined, nor something like BSD for example. (On the other hand, sparc, __sparc__, unix, __unix, __unix__, sun, __sun, etc are predefined in Soalris; __unix, __linux, etc are predefined in Linux; __APPLE__, __MACH__, __POWERPC__, etc are predefined in Mac OS.)
    So I guess in my particular case, I simply have to write
    #ifdef SVR4
    # include <siginfo.h>
    #else
    # include <signal.h>
    #endif
    unless and until I encounter an OS that predefines SVR4 but does not have <siginfo.h>, or an OS that does not predefine SVR4 but has psignal() declared in <signal.h>. Then I have to find a way to somehow further distinguish among them, assumed I do not use a tool such as autoconf.
    Last edited by hzmonte; 11-04-2005 at 04:17 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can someone please clean up my code
    By ki113r in forum C Programming
    Replies: 10
    Last Post: 09-12-2007, 10:03 AM
  2. opengl program as win API menu item
    By SAMSAM in forum Game Programming
    Replies: 1
    Last Post: 03-03-2003, 07:48 PM
  3. Printing weekday
    By sworc66 in forum C Programming
    Replies: 12
    Last Post: 09-13-2002, 07:03 AM
  4. Changing bkgrnd color of Child windows
    By cMADsc in forum Windows Programming
    Replies: 11
    Last Post: 09-10-2002, 11:21 PM
  5. rand()
    By serious in forum C Programming
    Replies: 8
    Last Post: 02-15-2002, 02:07 AM