Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84 SMI; site sun.uucp Path: utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!zeta!sabre!petrus!bellcore!decvax!decwrl!sun!guy From: guy@sun.uucp (Guy Harris) Newsgroups: net.unix-wizards Subject: Re: PCC, lint bug Message-ID: <2729@sun.uucp> Date: Fri, 30-Aug-85 00:17:13 EDT Article-I.D.: sun.2729 Posted: Fri Aug 30 00:17:13 1985 Date-Received: Sun, 1-Sep-85 04:48:26 EDT References: <1024@brl-tgr.ARPA> Organization: Sun Microsystems, Inc. Lines: 32 This really belonged in net.lang.c, for reasons which will be apparent shortly... > The following totally reasonable looking garbage compiles and passes > lint -hp without a peep. It printed garbage on my 4.2 VAX, core dumped > on my UNIX/PC (SYSV). I realize the difference between a two dimensional > array and a pointer to a pointer (or whatever, pluralize), apparently > neither C nor lint does. Sorry if this has been covered. > (excerpted) > ---------- > int x[2][2] ; > int **xp = x ; > printf("%d\n",x[i][j] = i+j) ; > printf("%d\n",xp[i][j]) ; C does know the difference between "array of X" and "pointer to X"; however, when the name of an "array of X" is used it evaluates to a pointer to the first member of that array, hence a "pointer to X". xp[i][j] is (xp[i])[j]. xp[i] is *(xp + i). "xp" is a pointer to a pointer to an "int", as is xp + i. *(xp + i) is thus a pointer to an "int". (xp[i])[j] is thus (*(xp + i))[j]. Call *(xp + i) Xp. (xp[i])[j] is Xp[j]. This is *(Xp + j). "Xp" is a pointer to an int, as is Xp + j, so *(Xp + j) is an "int". The code is perfectly legal C. Any C compiler or "lint" which *rejected* it would have a bug. Why the program drops core is left as an exercise for the reader. (Hint - has what "xp" points to been initialized? Is code that dereferences an uninitialized pointer likely to work?) Does anybody else think that the array/pointer semi-equivalence is probably one of the major causes of errors in C coding? Guy Harris