Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site birtch.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!decvax!ittatc!dcdwest!sdcsvax!sdcrdcf!trwrb!scgvaxd!felix!birtch!oleg From: oleg@birtch.UUCP (Oleg Kiselev) Newsgroups: net.lang.c Subject: Re: mildly obfuscating c Message-ID: <164@birtch.UUCP> Date: Wed, 11-Dec-85 00:05:55 EST Article-I.D.: birtch.164 Posted: Wed Dec 11 00:05:55 1985 Date-Received: Sat, 14-Dec-85 07:50:00 EST References: <564@puff.UUCP> Reply-To: oleg@birtch.UUCP (Oleg Kiselev) Distribution: net Organization: The Real Estate Conspiracy Lines: 68 In article <564@puff.UUCP> tom@puff.UUCP writes: >ok, guys, now i will admit that the below code is *not* kosher. >but the question still remains, if you run this program, what will >your output be? does the machine you compile it on make >a difference? does defining ARG to be something, say 999, >make a difference? what if VAR were auto or static? > >------------------------------------------------------------- ># define ARG ># define VAR register ># define CALL(x) (*(int (*)()) (x))(ARG) > >main() { > VAR thing = 0; >stuff: > printf("here it goes, thing is %d\n",thing); > if (!thing++) > CALL(stuff); > printf("one there it went, thing is %d\n",thing); > printf("two there it went, thing is still %d\n",thing); >} > > >/* lint outputs >test.c: >test.c(8): warning: questionable conversion of function pointer >*/ >------------------------------------------------------------- > >note the lint output. no kidding. .......[DELETED]........ >on a pyramid, this is the bizarre result: > >------------------------------------------------------------- >here it goes, thing is 0 >here it goes, thing is 536151860 >one there it went, thing is 536151861 >two there it went, thing is still 536151861 >one there it went, thing is 1 >two there it went, thing is still 1 >------------------------------------------------------------- Actually, this is not too bizarre.... This is the way it works on our Pyramid: The way the code is written, declaration of "thing" precedes the label. So, the routine call to stuff jumps to _stuff symbol address. _thing symbol is initialized by code located BEFORE _stuff address, probably by "movw $0,". Then there follows a printf call. If you do not take care of placing you variables outside the routine ( making them global) or declaring them static, Pyramid's C compiler will optimize EVERY possible variable to be "register" (&'d things are exempt, I think). So, what happens in THIS program is that the assignment to _thing is actually a register assignment. When you call a subroutine, the register frame on Pyramid shifts and a new set of registers is presented to the routine to use as local automatic storage. And the register where the code expects to find _thing ( some l-register?) is now uninitialized. That would mean also that if more than n (8?16?) calls are made recursively something will change ( when Pyramid's processor runs out of its 528(?) registers and has to push things on stack). Hey, anybody has time to check that? -- Disclamer: My employers go to church every Sunday, listen to Country music, and donate money to GOP. I am just a deviant. +-------------------------------+ Don't bother, I'll find the door! | "VIOLATORS WILL BE TOAD!" | Oleg Kiselev. | Dungeon Police |...!{trwrb|scgvaxd}!felix!birtch!oleg --------------------------------+...!{ihnp4|randvax}!ucla-cs!uclapic!oac6!oleg