kim@amdahl.UUCP (04/02/87)
[ For all you do ... this line's for you ... ] I'm posting this for Robert Mitchell here at Amdahl. I've run into similar problems, but never really organized my thoughts on the subject. Seems like a topic worthy of some discussion here on the net. Note that I'm NOT cross-posting this to comp.lang.c since we're talking about dealing with two specific Amiga compilers, and not writing portable code in general. /kim From Robert Mitchell: Leo Schwab is one of the most creative and productive people on the net. I really like what he did with ROBOTROFF. Converting it to Lattice, however, was painful. Porting software between compilers within the Amiga architecture can be (relatively) easy if authors follow some basic guidelines. There seem to be two primary problems in the Manx-to-Lattice (or vice-versa) translation: 1) Manx defaults to 16 bit integers and Lattice uses 32 bit. 2) Assembly language subroutines in Manx expect 16 bit integer parameters, while Lattice promotes to 32 bit. Use of the following conventions would make porting (and debugging) MUCH easier: 1) Do not type functions as returning "void *". Not only do we lose compiler type checking, it makes it harder for us Amiga novices to understand the code. 2) Amiga data structures frequently use "UWORD" types for unsigned 16 bit integers. NEVER cast these as (int); use (short) for math computations. This guarantees sign extension for fields like "spr.x" which is "UWORD". Why unsigned integers contain negative numbers is an area I have not explored. 3) Be extremely careful about type matching when using call by reference; the compiler can not help. "startxy(&spr.x,&spr.y)" causes memory overlays when the function declares these as integers. 4) Assembly language subroutines will always take some re-write because of the parameter passing differences. It would be preferable to code functions such as "rnd.asm" in "C", even at the cost of execution time. It would then port nicely. 5) It would help a lot to get rid of excess warning messages by typing local subroutines with no return codes as "static void". This also cuts down on the number of external labels. This one is just my bias, and is not directly related to porting. I hope this is of some use. I am certainly not finding fault with contributed software, and these reflect only my opinions. Robert Mitchell (408) 746-8491 -- UUCP: kim@amdahl.amdahl.com or: {sun,decwrl,hplabs,pyramid,ihnp4,seismo,oliveb,cbosgd}!amdahl!kim DDD: 408-746-8462 USPS: Amdahl Corp. M/S 249, 1250 E. Arques Av, Sunnyvale, CA 94086 CIS: 76535,25 [ Any thoughts or opinions which may or may not have been expressed ] [ herein are my own. They are not necessarily those of my employer. ]
dillon@CORY.BERKELEY.EDU.UUCP (04/02/87)
I now have both Lattice and Aztec C, and I've found that it's virtually impossible to write code compatible with both and still be able to write efficiently. Personally, I now use Aztec almost exclusively (Thanks Jim!), and even though I always use the +L option for 32 bit ints, my code would still require quite a bit of hacking of the header files before one could get it to work with Lattice. In fact, even Aztec users would have to do some hacking to be able to compile it since I use a very automated enviroment (have cc and ln aliased, etc...). This is one of the reasons why I've stopped posting source for programs such as DME.... I have no desire to spend 12 hours making it work on other peoples compiler enviroments, or even to standardize it to a generic enviroment. I rely heavily on my shell and the existance of certain control files (my 'standard' enviroment) when working on a program. BTW, the source is *still* available on request if anybody's interested. Also, I've noticed that 32 bit ints don't really increase code size all that much. What really makes the difference is the small code and data model (using relative address for globals). -Matt
ewhac@well.UUCP (04/04/87)
In article <6082@amdahl.UUCP> kim@amdahl.UUCP (really Robert Mitchell) writes: > >[ For all you do ... this line's for you ... ] > >I'm posting this for Robert Mitchell here at Amdahl. [ ... ] > >From Robert Mitchell: > At last. Some comments on the quality of my code. I've been interested to know this for some time. While I appreciate the comments, I thought you might equally be able to appreciate my perspective. > Leo Schwab is one of the most creative and productive > people on the net. I really like what he did with > ROBOTROFF. > > Converting it to Lattice, however, was painful. I never said it wouldn't be. Especially difficult should have been _main.c, because of the fundamentally different startup code of the two compilers. I would be interested to know what *exactly* was required to make Robotroff compiler and run under Lettuce. I know the next statement is terribly myopic, but the Manx code seemed relatively clean to me. > Porting software between compilers within the Amiga > architecture can be (relatively) easy if authors > follow some basic guidelines. > There seem to be two primary problems in the Manx-to-Lattice > (or vice-versa) translation: > > 1) Manx defaults to 16 bit integers and Lattice uses 32 bit. > 2) Assembly language subroutines in Manx expect 16 bit > integer parameters, while Lattice promotes to 32 bit. > Um... er... Assembly, per se, doesn't *expect* anything. I could have supplied the random number generator I wrote for Lettuce and declared it extern long, and it would have worked great (if I passed it a long). I should have called attention to this gotcha. > Use of the following conventions would make porting (and debugging) > MUCH easier: > > 1) Do not type functions as returning "void *". Not > only do we lose compiler type checking, it makes it > harder for us Amiga novices to understand the code. > Okay, I'll try. I usually only type Amiga library functions as returning either void * (if they return a pointer to anything), or long (if they return an integral value of some sort). Some might say, "Why not #inlcude <functions.h>?" Well, in the 3.20 version of the compiler, there are ommisions and errors in that file (the exact nature of which I haven't studied of late, but it is there). Also, I like having the type checking turned off, especially with GetMsg(). GetMsg() almost never returns a struct Message *, but a struct IntuiMessage *, or a struct IOStdReq *, etc. Explicitly coercing the type over to what it should be strikes *me personally* as rather painful, and makes the code more difficult to read, adding more parenthesis and making it look like a LISP program :-). I know, weak excuses, but that's what happens when you become rather familiar with the operation of the processor and compiler, and you know what you can get away with. I suppose ANSI will visit me one day and ask me to please stop that. > 2) Amiga data structures frequently use "UWORD" types > for unsigned 16 bit integers. NEVER cast these as (int); > use (short) for math computations. This guarantees > sign extension for fields like "spr.x" which is "UWORD". > Why unsigned integers contain negative numbers > is an area I have not explored. > A very valid point. Once again, an assumption on compiler behavior. Sorry. > 3) Be extremely careful about type matching when using > call by reference; the compiler can not help. > "startxy(&spr.x,&spr.y)" causes memory overlays > when the function declares these as integers. > Erp. Excuse me. I'll be more careful. > 4) Assembly language subroutines will always take some > re-write because of the parameter passing differences. > It would be preferable to code functions such as > "rnd.asm" in "C", even at the cost of execution time. > It would then port nicely. > ^^^^^^^^^^^^^^^^^^^^^^^^^ And if you believe that, I have a bridge to sell you :-) :-). > 5) It would help a lot to get rid of excess warning messages > by typing local subroutines with no return codes as "static void". > This also cuts down on the number of external labels. > This one is just my bias, and is not directly related > to porting. > Hmm. I like that one. I'll try it. > I hope this is of some use. I am certainly not finding fault > with contributed software, and these reflect only my opinions. > > Robert Mitchell > (408) 746-8491 And your opinions are appreciated. Really. Anything I can do to be a better programmer will be effort well-spent. Thanks. _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ ________ ___ Leo L. Schwab \ /___--__ The Guy in The Cape ___ ___ /\ ---##\ ihnp4!ptsfa!well!ewhac / X \_____ | __ _---)) ..or.. / /_\-- -----+==____\ // \ _ well ---\ ___ ( o---+------------------O/ \/ \ dual ----> !unicom!ewhac \ / ___ \_ (`o ) hplabs -/ ("AE-wack") ____ \___/ \_/ Recumbent Bikes: "Work FOR? I don't work FOR The _O_n_l_y Way To Fly! anybody! I'm just having fun."
mwm@eris.UUCP (04/05/87)
In article <2865@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes: >In article <6082@amdahl.UUCP> kim@amdahl.UUCP (really Robert Mitchell) writes: >> 1) Manx defaults to 16 bit integers and Lattice uses 32 bit. >> 2) Assembly language subroutines in Manx expect 16 bit >> integer parameters, while Lattice promotes to 32 bit. >> > Um... er... Assembly, per se, doesn't *expect* anything. I could >have supplied the random number generator I wrote for Lettuce and declared >it extern long, and it would have worked great (if I passed it a long). I >should have called attention to this gotcha. Uh, is there anything wrong with using the supplied version of rand() and srand() for your random number generator? They're ANSI standard, so should run on anything. Of course, if you need a good PRN, you might wanna check out your version first.... Founder of the Committee to Reuse Code Everywhere, <mike -- Here's a song about absolutely nothing. Mike Meyer It's not about me, not about anyone else, ucbvax!mwm Not about love, not about being young. mwm@berkeley.edu Not about anything else, either. mwm@ucbjade.BITNET
papa@bacall.UUCP (04/05/87)
> From Robert Mitchell: > > Leo Schwab is one of the most creative and productive > people on the net. I really like what he did with > ROBOTROFF. > > Converting it to Lattice, however, was painful. > Porting software between compilers within the Amiga > architecture can be (relatively) easy if authors > follow some basic guidelines. > There seem to be two primary problems in the Manx-to-Lattice > (or vice-versa) translation: > > 1) Manx defaults to 16 bit integers and Lattice uses 32 bit. > 2) Assembly language subroutines in Manx expect 16 bit > integer parameters, while Lattice promotes to 32 bit. This is not true. What you call assembly language subroutines are actually the Amiga library routines. These have ALWAY expected 32 bits for their parameters. So, no matter which compiler and model you use, you must pass 32-bit paramters to them. There is never a problem when passing pointers, since they are always 32-bits. The problem comes when passing ints. With Lattice, all is easy since sizeof(int)=sizeof(long)= 32bits. With MANX it depends on the model used. Using the model with 32-bit ints, one gets larger code, but retains compatibility with Lattice. Using the model with 16-bit ints, one has to cast ints to longs when passing parameters to ROM kermel routines. Also one has to add the letter L to EVERY constant that is passed, since by default constants are of type int in C. -- Marco Papa -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Marco Papa 3175 S. Hoover St., Ste. 275 (213)747-8498 Los Angeles, CA 90007 USC: (213)743-3752 F E L S I N A Now working for ::::::: BIX: papa But in no way :: :: Officially representing ::::::: ...!usc-oberon!bacall!papa S O F T W A R E papa@usc-cse.usc.edu -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
dillon@CORY.BERKELEY.EDU.UUCP (04/07/87)
>> From Robert Mitchell: >> 1) Manx defaults to 16 bit integers and Lattice uses 32 bit. >> 2) Assembly language subroutines in Manx expect 16 bit >> integer parameters, while Lattice promotes to 32 bit. > >This is not true. What you call assembly language subroutines are actually >the Amiga library routines. These have ALWAY expected 32 bits for their >parameters. So, no matter which compiler and model you use, you must pass >32-bit paramters to them. There is never a problem when passing pointers, >since they are always 32-bits. The problem comes when passing ints. With >-- Marco Papa You misinterpreted Robert's comment, Marco. He was *NOT* talking about the assembly interface to the Amiga library, he was talking about assembly support routines that many people write for their programs. Those people who are used to Manx w/16bit ints write their assembly routines expecting short's for int's on the stack whereas somebody writing assembly for Lattice or Manx-32bit would always expect long's for ints on the stack. -Matt
papa@bacall.UUCP (04/08/87)
> > > >> From Robert Mitchell: > >> 1) Manx defaults to 16 bit integers and Lattice uses 32 bit. > >> 2) Assembly language subroutines in Manx expect 16 bit > >> integer parameters, while Lattice promotes to 32 bit. > > > >This is not true. What you call assembly language subroutines are actually > >the Amiga library routines. These have ALWAY expected 32 bits for their > >parameters. So, no matter which compiler and model you use, you must pass > >32-bit paramters to them. There is never a problem when passing pointers, > >since they are always 32-bits. The problem comes when passing ints. With > >-- Marco Papa > > You misinterpreted Robert's comment, Marco. He was *NOT* talking > about the assembly interface to the Amiga library, he was talking about > assembly support routines that many people write for their programs. Those > people who are used to Manx w/16bit ints write their assembly routines > expecting short's for int's on the stack whereas somebody writing assembly > for Lattice or Manx-32bit would always expect long's for ints on the stack. > > -Matt True and not true. Robert says that "Assembly languages subroutines in MANX expects 16 bit integers", and you are saying that this is true only for people "who are used to MANX w/16bit" not "Manx-32bit". This was basically my point. Assembly language routines expect what you tell them to expect. Going back to "C" portability, Thomas Plum in his "Writing Portable C Programs" tutorial at the USENIX 1986 conference gives the following suggestions: Some practical guarantees: char 8 bits (or more) short 16 bits (or more) long 32 bits (or more) int no guarantee use these types in preferences to int -- Marco -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Marco Papa 3175 S. Hoover St., Ste. 275 (213)747-8498 Los Angeles, CA 90007 USC: (213)743-3752 F E L S I N A Now working for ::::::: BIX: papa But in no way :: :: Officially representing ::::::: ...!usc-oberon!bacall!papa S O F T W A R E papa@usc-cse.usc.edu -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
guilford@rpics.UUCP (04/10/87)
I've read several articles dealing with the incompatibilities between lattice and manx C-compilers. This may be a naive question, but why is there such an incompatibility? Isn't the purpose of a High-Level-Language to avoid such problems. I can understand that manx has a small memory model that passes small ints to subroutines. It seems to me that as long as the entire program was compiled by the same compiler, this should not matter unless one used one's own assembler code. (It could also be a problem if one used 'int' and assumed that it was long--but since C doesn't specify the size of int, one should have used long anyways.) The other source of problems would be in what subroutines are supplied and possibly different reactions from the same subroutines in different versions. The reason that I am asking this is that I am tired of fighting with this incompatibility. I hate it when someone writes some nifty program, posts it on the net (source only), and specifies that it should be compiled under manx. I, however (regardless of whether this is good or bad) only have lattice. I try to compile the silly thing there, and I get a couple of screen fulls of errors. Now I can either try to hack the code to work, or hope that the author is going to post the binary at some future time. This seems to me to be a silly way to work. What I am really wondering is if the sources of the incompatibilities are in the above, fairly unavoidable, places, or whether the programmers are writing in sleazy, non-portable ways that are geared to work with the quirks of their favorite compiler (or is there some other incompatibility that I haven't thought of?)? I would think that people writing in C, using the starndard RKM routines would produce portable code. Is it really that difficult? I'm rather new at usenet, so I hope I haven't offended anyone. --Jim Guilford (guilford@csv.rpi.edu)
hsgj@batcomputer.UUCP (04/11/87)
In article <1102@rpics.RPI.EDU> guilford@rpics.RPI.EDU (Jim Guilford) writes: >I've read several articles dealing with the incompatibilities between >lattice and manx C-compilers. This may be a naive question, but why is there >such an incompatibility? Isn't the purpose of a High-Level-Language to avoid >such problems. [...good stuff...] >I would think that people writing in C, using the starndard RKM routines >would produce portable code. Is it really that difficult? > >--Jim Guilford >(guilford@csv.rpi.edu) I have never used Amiga Manx so this is written from a Lattice perspective. I think a lot of compatibliity problems are (aside from RKM calling conventions) the difference in the "standard" stdio packages on both compilers. I know that I just finished a routine that had to generate -true- random numbers. On every 4.2BSD cc I have used (under vax750, gould,sequent) the function is called "random()" and it returns an integer from 0 to MAXINT. In Lattice C, a similar function is called "lrand48()" and does the same thing but returns from 0 to MAXLONG. Why the name change? Lattice also didn't like the way some of the string routines were named and called some funny names, like "stccpy" for "strcpy". Before anyone flames, yes they do have a #define strcpy stccpy automatically so you can still use strcpy. Speaking of that, I believe someone said that Manx has the "index" function, while Lattice uses "stptok" to search for a substring. Who is standard? I don't know. But anyways, if your code relies on a lot of these idiosyncratically named functions, then it probably won't port. Note that these are easy to fix with #ifdefs and #defines, but only if you know that the problems exist. One last comment: Please notice that I have avoided compiler wars. Cash rewards accepted... -- Dan Green -- ARPA: hsgj%vax2.ccs.cornell.edu@cu-arpa.cs.cornell.edu UUCP: ihnp4!cornell!batcomputer!hsgj BITNET: hsgj@cornella
mwm@eris.UUCP (04/11/87)
In article <659@batcomputer.tn.cornell.edu> hsgj@tcgould.tn.cornell.edu.UUCP (Dan Green) writes: >In article <1102@rpics.RPI.EDU> guilford@rpics.RPI.EDU (Jim Guilford) writes: >>I've read several articles dealing with the incompatibilities between >>lattice and manx C-compilers. This may be a naive question, but why is there >>such an incompatibility? Isn't the purpose of a High-Level-Language to avoid >>such problems. Foolish mortal! C is one of the most portable languages around, but given two compilers from differen vendors, I can almost certainly produce code that will compile with one and not the other. There's a good chance I can also produce code that compiles on both, and gives radically different results. ("Almost certainly" instead of "certainly" because most Unix vendors use PCC as a base. That makes things harder.) >I have never used Amiga Manx so this is written from a Lattice perspective. Ditto. However, I have worked with people with Manx compilers to produce code that will compile/run under both. >I think a lot of compatibliity problems are (aside from RKM calling >conventions) the difference in the "standard" stdio packages on both >compilers. Yup. The other problem is that Manx makes an "int" 16 bits and Lattice makes it 32 bits. Since "ints" is the default size for function parameters & return values, things that aren't int's in those places cause problems. This is the source of the "RKM calling conventions" problems. Lattice people tend not to cast things (I'm guilty of that - I use function prototypes, which serves the same purpose). With Manx, code that passes non-int's without saying what's going on tends to die horribly. If Manx supported function prototyping, this problem wouldn't be so nasty. With Lattice, code broken as above tends to work. Lattice, of course, support function prototyping. >I know that I just finished a routine that had to generate >-true- random numbers. On every 4.2BSD cc I have used (under vax750, >gould,sequent) the function is called "random()" and it returns an integer >from 0 to MAXINT. In Lattice C, a similar function is called "lrand48()" >and does the same thing but returns from 0 to MAXLONG. Why the name >change? Yes, but if I type "man lrand48" on my big Unix box (lynx), I get a man page (which is odd, because on lynx, sizeof(short) = sizeof(long) = sizeof(int) = 64 bits). The catch is that Lynx doesn't run a BSD-derived Unix. It runs a SysIII/V derived Unix. Note that there are probably more of those around then 4BSD systems. In other words, Lattice didn't change the name, they just used a different Unix than you did. [Side note: random() & like don't produce -true- random numbers. At best, they produce a nice long sequece of pseudo-randome numbers. Many vendor-supplied functions for doing so do so _very_ poorly. If you're serious about needing a good source of "random" numbers, apply statistical test to your PRN generator to see if it meets your needs. If it doesn't right your own. Knuth Vol. 2 is a good place to start looking.] >Lattice also didn't like the way some of the string routines >were named and called some funny names, like "stccpy" for "strcpy". Before >anyone flames, yes they do have a #define strcpy stccpy automatically so >you can still use strcpy. In this case, sysV doesn't differ from BSD. Don't know why Lattice did this. Since the "correct" names work, it doesn't matter. >Speaking of that, I believe someone said >that Manx has the "index" function, while Lattice uses "stptok" to >search for a substring. Wrong on two counts. First, index() doesn't search for substrings, it searches for characters in a string. strchr() is the Lattice (and SysIII/V) equivalent. BSD doesn't have a stptok() equivalent. Maybe something like this is responsible for the "stccpy" names (but I doubt it, as strcpy is explicitly mentioned as being in the library in K&R). >Who is standard? I don't know. There is no standard. The best that can be done is the dpANS (Draft Proposed American National Standard). Lattice is working on following that, and the results can be seen in 3.10. Notice that dpANS trys to stay with SysIII/V libraries. These are different from the BSD libraries, which Manx copied. Hopefully, in future releases, Manx will have routines with the dpANS names. >But anyways, if your code relies on a lot of these idiosyncratically >named functions, then it probably won't port. No, it probably won't compile & run if you copy it. You'll have to make some changes. But experienced C programmers should be able to handle all of this with no problem. Final comment: I'm not trying to start a compiler war. Unfortunately, Manx doesn't provide near the dpANS compatability that Lattice does. I consider dpANS to be a good thing, as it will increase the portability of C programs. Because of this, the above posting may sound like I'm saying bad things about Manx. I am, in that *I* consider lack of dpANS compatability to be a bad thing (sort of like lack of flexnames). However, that is not the only basis for judging compiler, and some very good people consider it to be totally irrelevant. You've got to consider your applications, and select a compiler based on that. <mike -- Here's a song about absolutely nothing. Mike Meyer It's not about me, not about anyone else, ucbvax!mwm Not about love, not about being young. mwm@berkeley.edu Not about anything else, either. mwm@ucbjade.BITNET