How do a write portable programs?

Mark Jones jones at ingr.UUCP
Fri Sep 9 00:08:19 AEST 1988


In article <1056 at nmtsun.nmt.edu>, warner at hydrovax.nmt.edu (M. Warner Losh) writes:
> write portable 'C' code.  Things like don't use 0, use NULL, but be
> sure to always cast it.

Instead of using NULL, use ZERO, and don't worry about casting it.  In K
& R (first edition) page 192 the following statement is made regarding
assignment operators. "... it is guaranteed that assignment of the
constant 0 to a pointer will produce a null pointer distinguishable from
a pointer to any object." (For a very close look at this subject, get
sept/oct issue of "The C Users Journal" (published by CUG) pages 29-36.

> How do I write program that are easily protable when I HAVE TO use the
> system calls (be they setitimer() or lib$init_timer() or int21()...).  Is
> there a good and easy way that I can write my programs so that most of the
> code never has to be touched when I port?  What is the best way of handling
> system dependent routines?  Assume the whole world is UNIX and then write
> UNIX system call emulation on those that aren't?  Or should I write
> routines that will do some functions (say turn off echo, but that is a bad
> example) regardless of how that function gets done.  Should I use zillions
> of #ifdefs everywhere? or should there be files that contain source code
> for only one system? 
> 

If at all possible, stick to std K & R functions (if they are not in the
K & R book (first edition), don't use them.  If that isn't possible, try
to find a function in the ANSI C spec that will do what you want.  If
there still isn't one, write your own, and in that function, place your
#ifdefs to handle different OS, here is where you would place
lib$init_timer() and int21 calls.  Keep the main body of your code clear
of anything system dependent.

Do not rely on the size of anything.  If there is a need for a 32-bit
number, do it like this:

#if sizeof(int) == 4
typedef bit32 int			/* pick your own name here */
#else
#if sizeof(long) == 4
typedef bit32 long
#endif
#endif

Watch out for sign extension, If you plan to assign a character to an
int, declare it an unsigned if you want it to still be a character when
it gets there.  For example:
{
char c = 0x85;
int  i;				/* assuming 32 bit ints */
	i = c;		/* i = 0xffffff85 */
}
or
{
unsigned char c = 0x85
int i;
	i = c;		/* i = 0x00000085 */
}

For the next few years, try to stay with K & R, and don't use ANSI
extensions, this is because not everyone has the ANSI extensions.  For
examples, if you use prototypes (and you should), place them in a header
file and put #ifdefs around them.


> More files are easier to read, but harder to maintain, etc) 

Try to keep things broken into several files, based on functionality,
the small amount of overhead in maintaining the program is worth it when
it comes to getting it running on a foreign target, also, if the
communications facilities for porting the source are poor, it can save
some real headaches.

Mark Jones



More information about the Comp.lang.c mailing list