Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2(pesnta.1.3) 9/5/84; site epicen.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxn!ihnp4!pesnta!epicen!jbuck From: jbuck@epicen.UUCP (Joe Buck) Newsgroups: net.lang.c Subject: Re: mildly obfuscating c Message-ID: <288@epicen.UUCP> Date: Tue, 10-Dec-85 02:27:46 EST Article-I.D.: epicen.288 Posted: Tue Dec 10 02:27:46 1985 Date-Received: Thu, 12-Dec-85 05:02:59 EST References: <564@puff.UUCP> Reply-To: jbuck@epicen.UUCP (Joe Buck) Distribution: net Organization: Entropic Processing, Inc., Cupertino, CA Lines: 81 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. > > >on a vax, i get a reserved intruction trap as soon as i call the >label. On a Vax, subroutines called by the CALLS instruction (which is what the compiler generates) start with a two-byte register save mask. There isn't one at the label, rather there's some random pattern, hence the trap. I can't give details for other machines, but you can rest assured that registers and stack won't be saved and restored properly in most cases. That's the real reason this isn't valid. >i haven't been able to figure out anyway to "goto" a label that >i don't know. for example, i would like to do this: > >------------------------------------------------------------- >main() { > int (*jump[])() = { l1,l2,l3,l4,l5,l6,l7,l8 } > > l1: /* code */ > l2: /* code */ >... > l8: /* code */ > > goto *jump[whatever] >} >aside from the forward-referencing problem of the unseen labels, >this is a still syntax error. anyone have any way to do this? >tom Sure do. switch(whatever) { case 0: /* code at l1 above */ break; /* unless your intention is to fall through to the next case */ case 1: /* code at l2 above */ ... case 7: /* code at l8 above */ } etc. This should have identical effect, and will compile into code that looks very much like the above in many cases. There are rare situations where goto's are reasonable (I never use them myself), but I really think you should get out of the habit of thinking that way. -- Joe Buck | Entropic Processing, Inc. UUCP: {ucbvax,ihnp4}!dual!epicen!jbuck | 10011 N. Foothill Blvd. ARPA: dual!epicen!jbuck@BERKELEY.ARPA | Cupertino, CA 95014