[comp.sys.amiga.tech] M2/C discussion

dsking@pyr.gatech.EDU ( David King) (07/05/89)

In article <18213@usc.edu> papa@pollux.usc.edu (Marco Papa) writes:
>I've been told by a third party the this is not entirely true. Can you have 
>procedure pointers as fields of data structure as in:
>
>struct xpr {
>	long (*xpr_open)();
>	long (*xpr_close)();
>	....
>}
>
>...
>struct xpr *io;
>
>io->xpr_open = MyOpen;
>io->xpr_close = MyClose;
>
>Can you do that in M2?  I'd really like to know? Also does M2 provide
>setjmp/longjmp in one of the libraries?
>

	Yep, you can do that in M2.  Here's the equivalent code:

TYPE xprType = RECORD
		xprOpen,
		xprClose : PROC;
		...
	       END;
...
VAR io : xprType;
...
    WITH io DO
      xprOpen := MyOpen;
      xprClose := MyClose;
    END; (* With *)
...

#ifdef RAMBLE

	I actually use this in my present project (when I have time I'm working
on a very small terminal program since I don't have much free memory) to have 
all open windows use the same IDCMP port.  Each window's UserData pointer 
references a structure/RECORD of procedure pointers for each type of message.
I use this feature so much I go crazy on ISO pascal compilers.

	setjmp/longjmp?  Its definately not part of the language definition
(they actually aren't part of C's definition unless the ANSI committee added 
it in the last year), and I couldn't find anything like it in M2Sprint's 
definitions.  *jmp actually are library routines on UNIX that got used in 
programs so much that they made it into most C systems.  This brings up 
something I've been wondering - what are things like *jmp useful for in an 
Amiga program?

#endif

	-David
	
>-- Marco Papa 'Doc'
>-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>uucp:...!pollux!papa       BIX:papa       ARPAnet:pollux!papa@oberon.usc.edu
>"There's Alpha, Beta, Gamma, Diga and Caligari!" -- Rick Unland
>-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
				       ^^^^^^^^
					Slowly the list grows longer.  Is this
a progression towards the "ultimate" customers as debuggers?

-- 
 David King - 	FROM Disclaimers IMPORT Standard;
Georgia Insitute of Technology, Atlanta Georgia, 30332
uucp: ...!{akgua,allegra,amd,hplabs,ihnp4,seismo,ut-ngp}!gatech!gitpyr!dsking
ARPA: dsking@pyr.gatech.edu

papa@pollux.usc.edu (Marco Papa) (07/05/89)

In article <8673@pyr.gatech.EDU> dsking@pyr.UUCP ( David King) writes:
>In article <18213@usc.edu> papa@pollux.usc.edu (Marco Papa) writes:
>>Does M2 provide setjmp/longjmp in one of the libraries?
					       ^^^^^^^^^
>	setjmp/longjmp?  Its definately not part of the language definition
>(they actually aren't part of C's definition unless the ANSI committee added 
>it in the last year), 

Maybe you should read more closely next time:-) I said 'libraries', not 
whether they are part of the language definition. Practically every C 
compiler that I have seen provides them, whether it runs under UNIX or 
other operating systems (PC-DOS, AmigaDOS, etc...).

>and I couldn't find anything like it in M2Sprint's 
>definitions.  *jmp actually are library routines on UNIX that got used in 
>programs so much that they made it into most C systems.  This brings up 
>something I've been wondering - what are things like *jmp useful for in an 
>Amiga program?

They are the easiest way to get out of an "error" or "abort" situation in 
one quick shot without having to add error checks on returns from functions
everywhere.  For example most ZMODEM and Kermit implementations have a single
'setjmp' at the start of the transfer which is then reached with a 'longjmp'
in case of an abort/error condition.

-- Marco Papa 'Doc'
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
uucp:...!pollux!papa       BIX:papa       ARPAnet:pollux!papa@oberon.usc.edu
"There's Alpha, Beta, Gamma, Diga and Caligari!" -- Rick Unland
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

doug@xdos.UUCP (Doug Merritt) (07/05/89)

In article <8673@pyr.gatech.EDU> dsking@pyr.UUCP ( David King) writes:
>	setjmp/longjmp?  Its definately not part of the language definition
>(they actually aren't part of C's definition unless the ANSI committee added 
>it in the last year),

Surprising; I was also surprised when I failed to find them in K&R just
now.

>  *jmp actually are library routines on UNIX that got used in 
>programs so much that they made it into most C systems. 

Well, the fact that they're library routines is irrelevent. There are a
fair number of library routines that are a standard part of the
definition of the C language, including e.g. printf() and strlen().
It's part of the charm of C that i/o and string handling "builtins" are
first class citizens in this way.

>something I've been wondering - what are things like *jmp useful for in an 
>Amiga program?

The cleanest, most defensible use is as a non-local goto to unwind
from deep procedures as part of error recovery. Even the purist Niklaus
Wirth uses (and advocates) non-local goto's for this purpose. Without
setjmp/longjmp, C has no non-local goto at all, and loses this ability.
Makes severe-error handling routines in complex software very messy.
That's why I surprised they're not in the standard.

They're also defined cleanly enough that it's hard to imagine a modern
day general purpose cpu that would have trouble allowing their
implementation, so I wonder why they didn't get included.
Hmmm...perhaps something like a Z8000 with different address spaces for
data and stack? I'm not really awake yet, anybody know?
	Doug
-- 
Doug Merritt		{pyramid,apple}!xdos!doug
Member, Crusaders for a Better Tomorrow		Professional Wildeyed Visionary

daveh@cbmvax.UUCP (Dave Haynie) (07/07/89)

in article <8673@pyr.gatech.EDU>, dsking@pyr.gatech.EDU ( David King) says:
> This brings up something I've been wondering - what are things like *jmp 
> useful for in an Amiga program?

Here's what I use 'em for:

#include <

jmp_buf lomem;

void *salloc(unsigned long amount) {
   void *mem;

   if (mem = AllocMem(amount,0L)) return mem;
   longjmp(lomem,1);
}

main() {

   /* ... */

   if (setjmp(lomem)) cleanup("Error: Out of memory");

  /* ... */
}

With that code, I know that the salloc() routine will always succeed.
Thus, I never need to check for the success of a memory allocation.  If you're
doing lots of allocation, this'll save you lots of writing and ugliness all
throughout your code, as well as the crash that results the one time you
forgot to check to see if AllocMem() really succeeded.  

I really miss this capability in M2 and C++...

>  David King - 	FROM Disclaimers IMPORT Standard;
-- 
Dave Haynie Commodore-Amiga (Systems Engineering) "The Crew That Never Rests"
   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: D-DAVE H     BIX: hazy
           Be careful what you wish for -- you just might get it