Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!olivea!tymix!cirrusl!sunstorm!dhesi From: dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) Newsgroups: comp.std.c Subject: Re: Frustrated trying to be portable Keywords: ANSI C, standard library Message-ID: <2956@cirrusl.UUCP> Date: 18 Feb 91 21:46:31 GMT References: <1991Feb17.203337.20569@uokmax.ecn.uoknor.edu> Sender: news@cirrusl.UUCP Distribution: na Organization: Cirrus Logic Inc. Lines: 68 In <1991Feb17.203337.20569@uokmax.ecn.uoknor.edu> clgreen@nsslsun.gcn.uoknor.edu (Cliff Green) writes: I'm getting somewhat frustrated in making a fairly complex package I'm working on to be portable....I'm trying to make portable between various hardware and os's (Unix, VMS on VAXen, Sun, SGI, etc.). Good! Portability is a worthwhile goal. Quickly realizing the uses of ANSI C, I ordered the standard (thanks, FAQ) and had the sysadmin on our Suns install a copy of GCC. Good! Conformance to a standard is a worthwhile goal. VAX C seems to be pretty close in most of the basic aspects of the standard, but there still seems to be a lot missing...Specifically on the Sun I'm missing [some include files and functions]. And there's the rub! You are trying to attain two mutually-exclusive goals. Today, given that we are in a transition between traditional C and ANSI C, one of the best ways to be highly nonportable is to use pure ANSI C. So what can you do? Try this: 1. Use a PARAMS or similar macro to enclose the argument list in function prototypes in declarations. Use traditional syntax for function definitions. 2. Use a symbol STDINCLUDE. If it's defined, include the ANSI standard include files. If not, include traditional C include files only. Define it wisely. #ifdef STDINCLUDE # include # include #else extern char *malloc(); extern char *strcpy(), *strncpy(), *strcat(); extern int strlen(); #endif (Do not use __STDC__ above -- it's quite possible for a C environment that isn't strictly ANSI C to still provide ANSI C include files.) 3. If you need functions only provided by ANSI C, either write your own for other environments. For example, if you need memmove, use move_down and move_up instead and include code like the following. (Check the code for off-by-one errors before using it.) #ifdef NEED_MEMMOVE char *move_down(dest, src, len) char *dest, *src; unsigned len; { char *p = dest; while (len>0) { *dest++ = *src++; --len; } return p; } char *move_up(dest, src, len) char *dest, *src; int len; { char *p = dest; dest += len; src += len; while (len > 0) { *dest-- = *src--; --len; } return p; } #else # define move_down memmove # devine move_up memmove #endif The above hints are the ones that aren't well explained in standard textbooks. For many others, see books about portable C programming. -- Rahul Dhesi UUCP: oliveb!cirrusl!dhesi