Path: utzoo!attcan!uunet!midway!ncar!zaphod.mps.ohio-state.edu!usc!snorkelwacker!mintaka!spdcc!esegue!compilers-sender From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.compilers Subject: C to Pascal (was Help on disassembler/decompilers) Keywords: assembler, debug, translator Message-ID: <26629@mimsy.umd.edu> Date: 20 Sep 90 02:10:47 GMT References: <6839.26ea3b0e@vax1.tcd.ie> <4028@bingvaxu.cc.binghamton.edu> Sender: compilers-sender@esegue.segue.boston.ma.us Reply-To: chris@mimsy.umd.edu (Chris Torek) Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 64 Approved: compilers@esegue.segue.boston.ma.us In several articles several people talk about the conversion of some code using C pointers into Pascal. The C code is (edited a bit): list *head; insert(list *newelem) { register list **p, *i; for (p = &head; (i = *p) != NULL; p = &i->next) if (i->item >= newelem->item) break; newelem->next = i; *p = newelem; } kym@bingvaxu.cc.binghamton.edu (R. Kym Horsell) translates it incorrectly and claims that the translation `duplicates the same bug as the original code'. Although the translation is indeed buggy, the original is not. Our Moderator noted the problem with straightforward translation, but was a bit off and/or lacking in specifics. The problem is that C lets us compute &head and, in storing newelem in *p, we may be altering the variable `head'. Horsell's translation (which uses a `memory' array) falls down by not making `head' an element of that memory array. But this is not how a Pascal programmer would do it: procedure insert(newelem : list); var i, p : list; keepon : boolean; begin p := nil; i := head; keepon := true; while keepon and (i <> nil) do if i^.item >= newelem^.item then keepon := false else begin p := i; i := i^.next end; newelem^.next := i; if p = nil then head := newelem else p^.next := newelem end; Part of the bloat above is necessary only due to the lack of a break or exit-loop statement or short-circuiting evaluation; ideally the boolean could be discarded in favour of something like while i /= nil && i.item < newelem.item do p := i; i := i.next; elihw; but this still leaves the final `if p = nil then ...' test, which is what the pointer (here, to a global, but in general, a pointer to a regular variable rather than one restricted to `things in a heap') avoids. This relates back to the original topic (`decompiling') in that it is hard to describe some common `lower level' machine operations in some higher level languages. As such things go, C is better than most languages, although one remains hard-pressed to come up with reasonable source representations for machine code of the form adwc r0,(r1)+ # r0 <- r0 + (r1) + carry; r1 <- r1 + 4 rrc r0 # rotate r0 right, carry into msb, lsb to carry adwc r0,(r1) or similar. (These things are sometimes found in checksum algorithms, many of which are coded in assembler in the first place.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris -- Send compilers articles to compilers@esegue.segue.boston.ma.us {ima | spdcc | world}!esegue. Meta-mail to compilers-request@esegue.