Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #125942

Re: Treating a multi-dimensional array as one-dimensional

From Ben Bacarisse <ben.usenet@bsb.me.uk>
Newsgroups comp.lang.c
Subject Re: Treating a multi-dimensional array as one-dimensional
Date 2018-01-29 11:00 +0000
Organization A noiseless patient Spider
Message-ID <87inblexpp.fsf@bsb.me.uk> (permalink)
References <p4mq61$1k5n$1@gioia.aioe.org>

Show all headers | View raw


August Karlstrom <fusionfile@gmail.com> writes:

> I need to define a function which can handle two-dimensional array
> parameters of any size (both dimensions). The code below illustrates
> my current approach.
>
> 	#include <stdio.h>
> 	
> 	#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
> 	
> 	static void Print(const int *A, int m, int n)
> 	{
> 	    int i, j;
> 	
> 	    for (i = 0; i < m; i++) {
> 	        for (j = 0; j < n; j++) {
> 	            printf("%d ", A[i * n + j]);
> 	        }
> 	        putchar('\n');
> 	    }
> 	}
> 	
> 	int main(void)
> 	{
> 	    int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
> 	
> 	    Print((int *) A, LEN(A), LEN(A[0]));
> 	    return 0;
> 	}
>
> I posted this question on StackOverflow(*) and it was suggested that
> It violates the strict aliasing rule. Is there a different way to
> solve this problem?

Yes.  If the array size (specifically the row length) is not known at
compile time you can do this as of C99:

static void Print(int m, int n, int A[m][n])
{
     int i, j;

     for (i = 0; i < m; i++) {
          for (j = 0; j < n; j++) {
               printf("%d ", A[i][j]);
          }
          putchar('\n');
     }
}

Note the parameter order and the deleted const.  The new order is needed
but the const has gone simply to avoid a problem C has with const where
there is more than one level of indirection.

If at least the row size (3 in this case) is known at compile time you
need no "new" features:  Just pass a pointer to the first array
element -- an array of 3 int:

  static void Print(int (*A)[3], int m)

but the fact that you pass both m and n suggests this won't be suitable.

As for the "strict aliasing" issue, that's a red herring.  The code that
treats a 2D array as a 1D array is technically undefined for reasons
that have nothing to do with aliasing.  I doubt, though, that you will
come across a problem if you do it that way.  There's a lot of code out
there that does that, despite the letter of the language standard.

But if you can use variably modified types (the jargon for a run-time
array size parameter) then you get simpler code as well as code that is
correct by the letter of the language standard.

Finally, if (a) you can't use C99; (b) you want to avoid any hint of
undefined behaviour and (c) the arrays sizes are known at compile time
but the function must be general-purpose you can use an union.  I won't
post an example because this set of circumstances is unlikely.

-- 
Ben.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Treating a multi-dimensional array as one-dimensional August Karlstrom <fusionfile@gmail.com> - 2018-01-29 10:40 +0100
  Re: Treating a multi-dimensional array as one-dimensional Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-01-29 11:00 +0000
    Re: Treating a multi-dimensional array as one-dimensional supercat@casperkitty.com - 2018-01-29 07:58 -0800
    Re: Treating a multi-dimensional array as one-dimensional Nick Bowler <nbowler@draconx.ca> - 2018-01-29 22:38 +0000
      Re: Treating a multi-dimensional array as one-dimensional Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-01-29 23:07 +0000
  Re: Treating a multi-dimensional array as one-dimensional Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-01-29 03:29 -0800
    Re: Treating a multi-dimensional array as one-dimensional August Karlstrom <fusionfile@gmail.com> - 2018-01-29 21:35 +0100

csiph-web