Notes on writing portable C/Unix programs Experienced C programmers probably know all this stuff but I've tripped on these things myself. Many of them are also no longer valid since the establishment of the ANSI C and POSIX standards. For what it's worth... Include files and defines ========================= Use #include , not #include If you need SEEK_SET, SEEK_CUR, etc don't depend on to define them. If you need M_PI, don't depend on to define it. The prototype for memcpy() may be in or and even then varies from system to system. The prototypes for malloc(), free(), etc may be in or The O_RDONLY and related symbols (man open) can be defined in a variety of places including , , , etc. Include to define NULL. Math ==== Don't use sinf(), cosf(), etc. they're not always available. Be aware that pow(0,0)==1 on some systems but causes a domain error on others. Be aware that divide by zero isn't always caught on modern RISC systems. Look for a man page on handling floating point exceptions. The prototypes for atoi() and atof() may be in or The C language ============== Under K&R C be aware that float function parameters are always passed as doubles. For example, this is bad: void foo( x ) float x; { float *y; y = &x; /* x is really a double! */ printf("%f\n", *y); } Similarly, be aware that char parameters are always passed as ints. Empty initializers are bad: static int x[] = { }; Not all C compilers handle automatic aggregate initializations. For example, void foo() { float vector[3] = { 1.0, 2.0, 3.0 }; ... } vector could be defined as static: void foo() { static float vector[3] = { 1.0, 2.0, 3.0 }; ... } realloc( NULL, n ) doesn't always work as by ANSI on some Suns (note the NULL). Architecture dependencies ========================= Be aware that "long int" is not always the same size as "int". Be aware that sizeof(any pointer) is not four bytes on 64-bit systems. System-specific pitfalls ======================== strdup() is not available on DEC Ultrix systems and not in ANSI C spec. The prototype for strdup() is in stdlib.h on DEC alpha systems, not string.h On HP's you usually need to define -D_HPUX_SOURCE in your CFLAGS X11, GL and OpenGL ================== If need to include AND , include them in that order. Be sure to use -I$(SOMETHING) in your makefile to find X11 include files if not in /usr/include/X11 ranlib ====== Some Unix systems need to have ranlib applied to library (.a) files, others don't. Here's what I've found: configuration need ranlib? ---------------- ------------ IBM RS/6000, AIX no Amiga, AMIX no Data General, DGUX no FreeBSD yes generic GCC yes HP, HPUX no SGI, IRIX no PC, Linux yes MacIntosh, MachTen yes PC, NetBSD yes DEC, OSF/1 no PC, SCO unix no SunOS 4.x yes SunOS 5.x no DEC, Ultrix no PC, Unixware no Stardent, Vistra no Stardent, Stellix no Miscellaneous ============= Don't name a function "index" as there's sometime a string function with that name. Avoid the use of bcopy and bzero, and use memcpy and memset instead. Notice the arg order from memcpy is the reverse of bcopy. (thanks PH) On IRIX Use the -signed flag on your cc lines to force char declarations to be signed, or make sure that all char declarations are preceded by "signed" or"unsigned". Most comilers on Linux and Windows/NT default chars to signed char. (thanks PH) See also Portability.txt in Mark Kilgard's GLUT distribution.