Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c,misc.jobs.misc Subject: Re: weird c code/ c test Message-ID: <7761@mimsy.UUCP> Date: Thu, 30-Jul-87 07:23:06 EDT Article-I.D.: mimsy.7761 Posted: Thu Jul 30 07:23:06 1987 Date-Received: Sat, 1-Aug-87 08:06:54 EDT References: <1089@gilsys.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 65 Keywords: test, employment, weird, code, pointers Xref: mnetor comp.lang.c:3374 misc.jobs.misc:517 In article <1089@gilsys.UUCP> mc68020@gilsys.UUCP (Thomas J Keller) writes: >... See if you can determine the output of this program without actually >compiling it: > >#include > >char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; >char **cp[] = { c+3, c+2, c+1, c }; >char ****cpp = cp; Error: Illegal type combination: attempt to assign pointer to pointer to pointer to char (char ***) to object of type pointer to pointer to pointer to pointer to char (char ****). Remember, the type of `cp' is `array 4 of pointer to pointer to char'; when the name `cp' is used in a context other than `sizeof', this is altered by changing `array N of' to `pointer to', which gives `pointer to pointer to pointer to char'. That PCC compiles this without complaint simply means there is a bug in PCC. Guy Harris posted a fix not long ago. Assuming this was a typographic error fixes up the example (which happens to work on any machine where the sizes of (char ****), (char ***), (char **), and (char *) are equal). > (actually, the program AS PRESENTED probably wouldn't have compiled, as > the *c declaration was as follows: > > char *c[] = { "ENTER", "NEW", "POINT", "FRIST", }; > > ) There is nothing wrong with this. `c' is `array 4 of pointer to char', as before. (I assume "FRIST" is a typographic error, though in fact it does not affect the output.) Back to the code, changing the last declaration to `char ***cpp': printf("%s", **++cpp); ++cpp changes the value of cpp from &cp[0] to &cp[1]; *&cp[1] == cp[1]; cp[1] == &c[2]; *&c[2] is "POINT". printf("%s ", *--*++cpp+3); ++cpp changes its value from &cp[1] to &cp[2]; *&cp[2] == cp[2]. --cp[2] changes its value from &c[1] to &c[0]; *&c[0] == c[0], which points to the first character of "ENTER"; adding three points to the second E, so we print "ER ". printf("%s", *cpp[-2]+3); Cpp now points to &cp[2]; two back from this is &cp[0]. One dereference gives *&cp[0] == &c[3], another gives just c[3] which points to the F in "FIRST"; adding three we print "ST". printf("%s\n", cpp[-1][-1]+1); Cpp still points to &cp[2]. cpp[-1] is cp[1] or &c[2]; (&c[2])[-1] is the same as (c+2)[-1] or *((c+2)+(-1)) or *(c+1), which points at the N in "NEW". Adding 1, we get "EW". And now I have finished my bread and will go make some mixed vegetables to fill out breakfast. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: seismo!mimsy!chris