Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site dg_rtp.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!whuxl!whuxlm!akgua!mcnc!rti-sel!dg_rtp!throopw From: throopw@dg_rtp.UUCP (Wayne Throop) Newsgroups: net.lang.c Subject: Re: Passing Multidimensional Arrays (and a modest suggestion) Message-ID: <34@dg_rtp.UUCP> Date: Sat, 14-Dec-85 16:26:19 EST Article-I.D.: dg_rtp.34 Posted: Sat Dec 14 16:26:19 1985 Date-Received: Mon, 16-Dec-85 03:56:45 EST References: <138@brl-tgr.ARPA> <365@codas.UUCP> Lines: 103 > > I have an application where I want to pass a 2D array to a subroutine. > > The data does not easily avail itself to being converted to a 1D array > > of structures. How can one access the array in the subroutine??? > How about this: > #define X 100 > #define Y 100 > struct x a[Y][X]; > subrout(i, j, a) > int i; > int j; > struct x *a[]; > { ...a[j][i]... } > And use i and j as boundary limits. > Mikel Manitius ...{ihnp4|akguc|attmail|indra!koura}!codas!mikel The main problem with this is that (although it is a legal C fragment), it shows neither the definition of x, nor an invocation of subrout. Thus, there is no clear notion as to what is supposed to be passed to the formal arguments i, j, and a. Also, the formal "a" hides the actual "a", and this is fairly confusing. Let me take this opportunity to recommend a practice that I try to follow (and regret whenever I backslide). Before posting an example, lint, compile, and (if possible) run it. For example, making reasonable guesses as to what was intended in the above example, we get a complete program like so: 1 #define X 100 2 #define Y 100 3 struct x { int f1, f2; }; 4 struct x a[Y][X]; 5 void subrout(i, j, a) 6 int i; 7 int j; 8 struct x *a[]; 9 { a[j][i]; } 10 11 void main(){ 12 subrout( X, Y, a ); 13 } which, of course, fails typecheck like so: line 12 inconsistent types discovered (:IDENTIFIER a :EXTERN ... ) Types are: (:ARRAY_OF (:POINTER_TO (:STRUCT x ( (:IDENTIFIER f1 :STRUCT_FIELD ... ) (:IDENTIFIER f2 :STRUCT_FIELD ... )))) () ()) and: (:POINTER_TO (:ARRAY_OF (:STRUCT x ( (:IDENTIFIER f1 :STRUCT_FIELD ... ) (:IDENTIFIER f2 :STRUCT_FIELD ... ))) 100 ())) Probing further, let's see what the compiler thought of the situation, by compiling it and fishing around with a debugger: 1> breakpoint 12 1> proceed Note: BREAKPOINT: LINE 12 OF main 1> describe a ARRAY [ 0..99 BOUND 32 ] OF ARRAY [ 0..99 BOUND 32 ] OF RECORD f1: INTEGER f2: INTEGER END RECORD BOUND 64 1> breakpoint 9 1> proceed Note: BREAKPOINT: LINE 9 OF subrout 1> describe a POINTER TO POINTER TO RECORD f1: INTEGER f2: INTEGER END RECORD BOUND 64 [ As an aside, I note that the debugger/compiler reports that the formal "a" is pointer-to-pointer, while the typechecker reports it as array-of-pointer. This is (sort of) correct for C, where formal arrays are "actually" pointers. The difference comes about in an understandable way, since the typechecker is trying to be purist, and the debugger has to know how the bits should "really" be treated. ] Now, I may have guessed wrongly about what Mikel intended. But I think it is clear that the example he posted is dangerously incomplete. I think it is also clear that the best available tools should be used to check out code fragments that are posted as examples for others to use. Without actually trying it out, I couldn't (without a fair amount of thought, vulnerable to error) have put my finger on exactly what was wrong with the fragment Mikel posted. -- Wayne Throop at Data General, RTP, NC !mcnc!rti-sel!dg_rtp!throopw