🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #37249

A Lesson Learned

#37249
From: Charles S. [Chip] Roberson
Date: Mon, 20 Mar 1989 22:54
75 lines
3771 bytes
Greetings fellow psycho-programmers!  Well, I just learned a lesson today
and I thought I pass it on to any others who haven't learned this, yet.
It only blew a day and a half of my time.

Below is a pretty slick fprintf() statement from some of the UUPC/ST code
munged enough to simplify this example.  Looking at it, I was sure that it
should work.  I mean, why not?  It's pretty straight forward -- pass
fprintf() 3 arguments: stderr, the appropriate format string, and finally
the desired value to print.  Then once the value is passed, increment.
Right? Wrong!

--------------------------------------------------------------------------
#include <stdio.h>
#include <ctype.h>

unsigned char charlie = 'I';

void oops() {
    unsigned char *cp;

	cp = charlie;
	fprintf( stderr, isprint(*cp)? "[%c]":"[%02x]", *cp++ );
}
--------------------------------------------------------------------------

MWC passes parameters in reverse order.  That means that the "*cp++"
gets evaluated BEFORE the "isprint(*cp)..." stuff.  So, everytime
fprintf will get passed the approprate character, but isprint is going
to look at whatever is in the next data location.  [In my case that was
usually garbage in an unused portion of a character buffer!]

For those of you who need to see the nasty stuff, here is a segment of the
MWC assembly code.  It should explain everything.  Especially, note the
lines that I marked with an '*'.  [Thanks to MWC's db pgm!]

--------------------------------------------------------------------------
        movea.l -8(a6), a0	;; move *cp into a0 for passing to fprintf()
*       addq.l  $1, -8(a6)	;; increment cp as specified in fprintf arg
        clr.w   d0		;; clean out cruft in d0
        move.b  (a0), d0	;; load value destined for passing to fprintf()
        move    d0, -(a7)	;; push it on the stack
*       movea.l -8(a6), a0	;; move *cp into a0 for isprint() check
        clr.w   d0		;; clean out some more cruft
        move.b  (a0), d0	;; stash *cp in d0 for testing
        swap.w  d0		;; toss it into the upper word
        clr.w   d0		;; clean out the lower word
        swap.w  d0		;; move *cp value back into lower word
        movea.l d0, a0		;; prep for isprint()
        adda.l  $_ctype_+1, a0	;; mung it a little
        move.b  (a0), d0	;; mung it some more
        ext.w    d0		;; ok, it's munged
        andi    $171, d0	;; does it map to printable set?
        beq.s   L10006		;; nope, go print it in hex
        pea     L37		;; yes, use character format in fprintf
        bra.s   L10007		;; go finish pushing args
L10006:
        pea     L38		;; use, hexidecimal format in fprintf
L10007:
        pea     _stderr_	;; finally, pass 1st arg to fprintf
        jsr     fprintf_	;; go do it!
--------------------------------------------------------------------------

The moral of this story?  Well, as my Theory of Prog. Lang prof would
say, "That's just another insecurity of C!"; to which he would add
"Ada is a much better language."  Well, I guess I would say
"Hey! Be careful out there."

Seriously, this is one side-effect that I hadn't thought about.  How
do other ST compiler's pass their parameters?  So much for portability,
eh?  Does anybody know how the dpANS standard would affect this, if at
all?  I can't seem to remember anything in it that would.

oh well.
cheers,
-c
Technical Details
Message-ID: <8903202254.AA00303@icase.edu>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!ICASE.EDU!csrobe

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!ICASE.EDU!csrobe
From: csrobe@ICASE.EDU (Charles S. [Chip] Roberson)
Newsgroups: comp.sys.atari.st
Subject: A Lesson Learned
Message-ID: <8903202254.AA00303@icase.edu>
Date: 20 Mar 89 22:54:30 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Organization: The Internet
Lines: 75