Passing Multidimensional Arrays (and a modest suggestion)

Wayne Throop throopw at dg_rtp.UUCP
Sun Dec 15 07:26:19 AEST 1985


> > 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
<the-known-world>!mcnc!rti-sel!dg_rtp!throopw



More information about the Comp.lang.c mailing list