passing pointer to a function expecting an array 
Author Message
 passing pointer to a function expecting an array

here's the deal...i have something like the following:

func(){
  double *G;

        do_something(G);

Quote:
}

do_something(Q)
double Q[][J][K][5];  /* J and K are constants */
{

/* do calculations involving access to all four array dimensions of Q */

Quote:
}

before you ask why i wrote it this way...i didn't! it's legacy code and
IIRC it was generated by matlab anyway. anyhoo....it's been tested and
it works with correct data output, etc. however i get warnings for every
such do_something call where the arg is just a double pointer. i was
trying to fix these warnings just because they annoy me (there's about
500 of them), but i'm having trouble doing it. any suggestions?

i tried defining a type like this:

  typedef double *qq_t[J][K][5];

and then declaring G in func to be of type qq_t (and Q in do_something is
as well). gets rid of the warnings, but i haven't tested the output yet.
it makes it a little hairy, however because of some of the pointer
arithmetic that's going on in func based on G being of type double
pointer.

thanks in advance,
joe.

"well, i was working on a new tax proposal and i accidentally proved that
there is no god..." - homer simpson



Wed, 11 May 2005 04:57:44 GMT  
 passing pointer to a function expecting an array

Quote:
> here's the deal...i have something like the following:

> func(){
>   double *G;

>      do_something(G);

This is odd. The value of is not defined. You intend to pass an undefined
value to a function. You may have a design error somewhere.

Quote:
> }

> do_something(Q)
> double Q[][J][K][5];  /* J and K are constants */
> {

This is aged C! Since 1989, a C function is written

/* J and K are constants */
int do_something (double Q[][J][K][5])
{

Hence the Q pointer has the type 'double ****', and must be a valid value.

Quote:
>   double *G;

is invalid :

- wrong type.
- not initialized.

Quote:
> /* do calculations involving access to all four array dimensions of Q */

I'm curious...

Quote:
> }

> before you ask why i wrote it this way...i didn't! it's legacy code and
> IIRC it was generated by matlab anyway. anyhoo....it's been tested and
> it works with correct data output, etc. however i get warnings for every
> such do_something call where the arg is just a double pointer. i was
> trying to fix these warnings just because they annoy me (there's about
> 500 of them), but i'm having trouble doing it. any suggestions?

> i tried defining a type like this:

>   typedef double *qq_t[J][K][5];

> and then declaring G in func to be of type qq_t (and Q in do_something is
> as well). gets rid of the warnings, but i haven't tested the output yet.
> it makes it a little hairy, however because of some of the pointer
> arithmetic that's going on in func based on G being of type double
> pointer.

Whatever the solution you find, you must keep in mind that using a non
initialized pointer invokes an Undefined Behaviour (IOW, it's a serious
bug)

--
-ed- emdel at noos.fr ~]=[o
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
C-library: http://www.dinkumware.com/htm_cl/index.html
"Mal nommer les choses c'est ajouter du malheur au monde."
-- Albert Camus.



Wed, 11 May 2005 06:56:01 GMT  
 passing pointer to a function expecting an array

Quote:

>here's the deal...i have something like the following:

>func(){
>  double *G;

>    do_something(G);
>}

>do_something(Q)
>double Q[][J][K][5];  /* J and K are constants */
>{

>/* do calculations involving access to all four array dimensions of Q */

>}

>before you ask why i wrote it this way...i didn't! it's legacy code and
>IIRC it was generated by matlab anyway. anyhoo....it's been tested and
>it works with correct data output, etc. however i get warnings for every
>such do_something call where the arg is just a double pointer. i was

If it produces the correct result, then G must actually point to the
first of a series of doubles and the number of doubles in the series
must be a multiple J*K*5.  This appears to be the 4D extension of the
popular 2D hack that i*columns+j will compute the linear displacement
of x[i][j] from x[0][0].

Quote:
>trying to fix these warnings just because they annoy me (there's about
>500 of them), but i'm having trouble doing it. any suggestions?

>i tried defining a type like this:

>  typedef double *qq_t[J][K][5];

>and then declaring G in func to be of type qq_t (and Q in do_something is
>as well). gets rid of the warnings, but i haven't tested the output yet.

If this gets rid of the warnings, then you need to either up your
warning level or get a new compiler.  That typedef declares an array
(of array of array) of pointers type which is not anything like what
you describe.  You have exactly one pointer (and an implied array of
array of array of array of doubles).

Quote:
>it makes it a little hairy, however because of some of the pointer
>arithmetic that's going on in func based on G being of type double
>pointer.

What you can do is

        typedef double (*qq_t)[J][K][5];

which declares a pointer to an array of array of array of doubles.  In
spite of the surface dissimilarities, this is exactly the type that
do_something is expecting.  Leave your definition of G alone but
whenever you call do_something, cast the argument to this type, as in

        do_something((qq_t)G);

<<Remove the del for email>>



Wed, 11 May 2005 07:36:27 GMT  
 passing pointer to a function expecting an array


Quote:

>> here's the deal...i have something like the following:

>> func(){
>>   double *G;

>>      do_something(G);

>This is odd. The value of is not defined. You intend to pass an undefined
>value to a function. You may have a design error somewhere.

>> }

>> do_something(Q)
>> double Q[][J][K][5];  /* J and K are constants */
>> {

>This is aged C! Since 1989, a C function is written

>/* J and K are constants */
>int do_something (double Q[][J][K][5])
>{

>Hence the Q pointer has the type 'double ****', and must be a valid value.

No, Q has type (*)[J][K][5].

- Show quoted text -

Quote:

>>   double *G;

>is invalid :

>- wrong type.
>- not initialized.

>> /* do calculations involving access to all four array dimensions of Q */

>I'm curious...

>> }

>> before you ask why i wrote it this way...i didn't! it's legacy code and
>> IIRC it was generated by matlab anyway. anyhoo....it's been tested and
>> it works with correct data output, etc. however i get warnings for every
>> such do_something call where the arg is just a double pointer. i was
>> trying to fix these warnings just because they annoy me (there's about
>> 500 of them), but i'm having trouble doing it. any suggestions?

>> i tried defining a type like this:

>>   typedef double *qq_t[J][K][5];

>> and then declaring G in func to be of type qq_t (and Q in do_something is
>> as well). gets rid of the warnings, but i haven't tested the output yet.
>> it makes it a little hairy, however because of some of the pointer
>> arithmetic that's going on in func based on G being of type double
>> pointer.

>Whatever the solution you find, you must keep in mind that using a non
>initialized pointer invokes an Undefined Behaviour (IOW, it's a serious
>bug)

<<Remove the del for email>>


Wed, 11 May 2005 11:53:40 GMT  
 passing pointer to a function expecting an array

Quote:

> here's the deal...i have something like the following:

> func(){
>   double *G;

I hope you've actually allocated some memory to G before the
following call!!

Quote:
>    do_something(G);
> }

> do_something(Q)
> double Q[][J][K][5];  /* J and K are constants */

double Q[][J][K][5] as an argument type is quietly
interpreted as double (*Q)[J][K][5] so Q is a pointer
but not to double. It is a pointer to three dimensional arrays
of double. So G should have been declared as:
double (*G)[J][K][5];

or

double G[SOME_DEFINED_MAX_DIMENSION][J][K][5];
(saves specifically doing the memory allocation)

Quote:
> {

> /* do calculations involving access to all four array dimensions of Q */

> }

> before you ask why i wrote it this way...i didn't! it's legacy code and
> IIRC it was generated by matlab anyway. anyhoo....it's been tested and
> it works with correct data output, etc. however i get warnings for every
> such do_something call where the arg is just a double pointer. i was
> trying to fix these warnings just because they annoy me (there's about
> 500 of them), but i'm having trouble doing it. any suggestions?

It works inspite of the error because Q and &(*Q)[0][0][0] represent
the same position in memory altough the first is compatible with a
pointer to a multy dimensional array of doubles while the second is
a compatible with a simple pointer to double.> i tried defining a type like this:

Quote:

>   typedef double *qq_t[J][K][5];

> and then declaring G in func to be of type qq_t (and Q in do_something is
> as well). gets rid of the warnings, but i haven't tested the output yet.

This makes the types af Q and G compatible but repesent something rather
different. In this case Q and G become arrays of pointers -- we now
actually have J*K*5 pointers -- each pointing to a double.

Somewhere somehow memory needs to be allocated for the doubles.

Quote:
> it makes it a little hairy, however because of some of the pointer
> arithmetic that's going on in func based on G being of type double
> pointer.

It sounds as though the processing in func might be exceedingly hairy
and remain so without a rewrite.
I suspect func linearises memory allocated to G as if it is a single
dimension array of double and the conversion to multidimension was to be
hidden in the function call.

Simlest way of eliminating the errors without actually fixing anthing is
probably to cast G in the call as
    do_something((double (*)[J][K][5])G)

Malcolm Kay



Wed, 11 May 2005 12:14:23 GMT  
 passing pointer to a function expecting an array
[...]

Quote:
>> do_something(Q)
>> double Q[][J][K][5];  /* J and K are constants */
>> {

> This is aged C! Since 1989, a C function is written

> /* J and K are constants */
> int do_something (double Q[][J][K][5])
> {

> Hence the Q pointer has the type 'double ****', and must be a valid value.

No, it has the type 'double (*)[J][K][5]' for want of a better way of
writing it.

        - Kevin.



Wed, 11 May 2005 12:32:57 GMT  
 passing pointer to a function expecting an array
malcolm kay wanted everyone in comp.lang.c to know that

Quote:
> I hope you've actually allocated some memory to G before the
> following call!!

yeah. i just forgot to put it in my post. memory is allocated and filled
with data.

Quote:
> double G[SOME_DEFINED_MAX_DIMENSION][J][K][5];
> (saves specifically doing the memory allocation)

but may use an unnecessary amount of memory.

Quote:
> Somewhere somehow memory needs to be allocated for the doubles.

it is for G in the calling function. which is then passed to the called
function.

Quote:
> I suspect func linearises memory allocated to G as if it is a single
> dimension array of double and the conversion to multidimension was to be
> hidden in the function call.

right. that's why it's hairy - linearising the accesses to G.

thanks to everyone for your suggestions. i'll check them out in the
morning.

--
joe.

"well, i was working on a new tax proposal and i accidentally proved that
there is no god..." - homer simpson



Wed, 11 May 2005 15:48:52 GMT  
 passing pointer to a function expecting an array

Quote:
>> /* J and K are constants */
>> int do_something (double Q[][J][K][5])
>> {

>> Hence the Q pointer has the type 'double ****', and must be a valid
>> value.

> No, it has the type 'double (*)[J][K][5]' for want of a better way of
> writing it.

All right.

--
-ed- emdel at noos.fr ~]=[o
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
C-library: http://www.dinkumware.com/manuals/reader.aspx
"Mal nommer les choses c'est ajouter du malheur au monde."
-- Albert Camus.



Wed, 11 May 2005 17:00:46 GMT  
 passing pointer to a function expecting an array

Quote:

> malcolm kay wanted everyone in comp.lang.c to know that

[...]

>>double G[SOME_DEFINED_MAX_DIMENSION][J][K][5];
>>(saves specifically doing the memory allocation)

> but may use an unnecessary amount of memory.

Not really relevant to the original topic,
but with J and K constant as suggested in your original
post then allocating memory using malloc or friends
has approximately the same expense in memory usage
as an auto allocation within the function. With the book-
keeping within malloc it is in fact probably a little
more expensive.

Having said that it must be admitted that there are
environments in which the amount of memory that can be
allocated with auto declarations is restricted as compared
with that possible with malloc.

Malcolm Kay



Wed, 11 May 2005 17:50:35 GMT  
 passing pointer to a function expecting an array
Barry Schwarz wanted everyone in comp.lang.c to know that

Quote:
> If it produces the correct result, then G must actually point to the
> first of a series of doubles and the number of doubles in the series
> must be a multiple J*K*5.  This appears to be the 4D extension of the
> popular 2D hack that i*columns+j will compute the linear displacement
> of x[i][j] from x[0][0].

right! that's exactly what it is.

Quote:
> If this gets rid of the warnings, then you need to either up your
> warning level or get a new compiler.

i'll check into changing the warning level. but i can't really get
another compiler. it's an MPI compiler, hcc, which is just the GNU gcc
compiler with an MPI compiler on top.

Quote:
> That typedef declares an array
> (of array of array) of pointers type which is not anything like what
> you describe.  You have exactly one pointer (and an implied array of
> array of array of array of doubles).

to clarify: if i do something like

typedef double *qq_t[J][K][5];

func(){
  qq_t G;
  /* malloc/assign data to G of course */
  call_func(G);

Quote:
}

call_func(qq_t Q){
  /* do some stuff with Q */

Quote:
}

THIS will get rid of the warnings. but since func was written with G as
a double *, i will have to change the way G is dealt with in func.

if i do as follows, i still have warnings:

func(){
  qq_t;
  /* malloc/assign data to G of course */
  call_func((qq_t)G);

Quote:
}

call_func(double Q[][J][K][5]){
  /* do some stuff with Q */

Quote:
}

which i think is as you described it should be. so perhaps my warning
level is fine....

Quote:
> What you can do is

>   typedef double (*qq_t)[J][K][5];

> which declares a pointer to an array of array of array of doubles.  In
> spite of the surface dissimilarities, this is exactly the type that
> do_something is expecting.  Leave your definition of G alone but
> whenever you call do_something, cast the argument to this type, as in

>   do_something((qq_t)G);

i tried this and it worked fine. thanks! it's fantastic not to see
hundreds of warnings fill your screen every time you try to compile :)

--
joe.

"well, i was working on a new tax proposal and i accidentally proved that
there is no god..." - homer simpson



Thu, 12 May 2005 03:39:03 GMT  
 passing pointer to a function expecting an array

Quote:

> Barry Schwarz wanted everyone in comp.lang.c to know that
>> If it produces the correct result, then G must actually point to the
>> first of a series of doubles and the number of doubles in the series
>> must be a multiple J*K*5.  This appears to be the 4D extension of the
>> popular 2D hack that i*columns+j will compute the linear displacement
>> of x[i][j] from x[0][0].

> right! that's exactly what it is.

>> If this gets rid of the warnings, then you need to either up your
>> warning level or get a new compiler.

> i'll check into changing the warning level. but i can't really get
> another compiler. it's an MPI compiler, hcc, which is just the GNU gcc
> compiler with an MPI compiler on top.

>> That typedef declares an array
>> (of array of array) of pointers type which is not anything like what
>> you describe.  You have exactly one pointer (and an implied array of
>> array of array of array of doubles).

> to clarify: if i do something like

> typedef double *qq_t[J][K][5];

That type is an array of arrays of arrays of pointers.  You want a pointer to
an array of arrays of arrays of doubles:

typedef double (*qq_t)[J][K][5];

Just remember that the * and [] operator-alikes in a declaration associate
the same way that the corresponding operators do in an expression.

        - Kevin.



Thu, 12 May 2005 15:45:56 GMT  
 passing pointer to a function expecting an array

Quote:

...
> > do_something(Q)
> > double Q[][J][K][5];  /* J and K are constants */
> > {

> This is aged C! Since 1989, a C function is written

"aged" doesn't have the connotation you want here;
try "antique", or to be a bit more judgemental "out-of-date"
or maybe "obsolete", but that last could be read as meaning
it's now illegal, and it's not, not even in C99.  Oh, and C89
wasn't actually deployed everywhere in 1989; people were
still validly writing old-style functions until the mid-1990's.
(And even today on some recalcitrant systems/vendors.)

Quote:
> /* J and K are constants */
> int do_something (double Q[][J][K][5])
> {

> Hence the Q pointer has the type 'double ****', and must be a valid value.

NO!  Array parameter type is adjusted to pointer,
and array value decays to pointer, ONLY at the
top/outermost level.  FAQ 6.18 et seq.
The type of this Q is double (*)[J][K][5].

In C99 (or gcc) J and K need not be constant.

...

Quote:
> > i tried defining a type like this:

> >   typedef double *qq_t[J][K][5];

That's a 3-dim array of pointers, which is quite
different from and very incompatible with a 4-dim array.
The pointer type that would be correct, assuming you
set its value to properly declared or allocated space, is
  typedef double (*qq_t) [J][K][5];

--
- David.Thompson 1 now at worldnet.att.net



Fri, 13 May 2005 09:55:01 GMT  
 passing pointer to a function expecting an array


Quote:
>> > do_something(Q)
>> > double Q[][J][K][5];  /* J and K are constants */
>> > {

>> This is aged C! Since 1989, a C function is written

> "aged" doesn't have the connotation you want here;

Ah, sorry about that.

Quote:
> try "antique", or to be a bit more judgemental "out-of-date"
> or maybe "obsolete", but that last could be read as meaning
> it's now illegal, and it's not, not even in C99.  Oh, and C89

Thanks.

--
-ed- emdel at noos.fr ~]=[o
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
C-library: http://www.dinkumware.com/manuals/reader.aspx
"Mal nommer les choses c'est ajouter du malheur au monde."
-- Albert Camus.



Fri, 13 May 2005 14:52:13 GMT  
 passing pointer to a function expecting an array
Groovy hepcat Emmanuel Delahaye was jivin' on 22 Nov 2002 22:56:01 GMT
in comp.lang.c.
Re: passing pointer to a function expecting an array's a cool scene!
Dig it!

Quote:

>int do_something (double Q[][J][K][5])

>Hence the Q pointer has the type 'double ****', and must be a valid value.

  BZZZZZZZZT! Wrong! It has type double (*)[J][K][5]. A pointer is not
an array. An array is not a pointer. A pointer and an array are not
the same. A pointer points. An array contains a number of consecutive
elements of a type.
  A pointer to a pointer is not a pointer to an array. A pointer to an
array is not a pointer to a pointer. A pointer to a pointer and a
pointer to an array are not the same. A pointer to a pointer points at
an object that points. A pointer to an array points at an object that
contains a number of consecutive elements of a type.
  A pointer to a pointer to a pointer is not a pointer to an array of
arrays. A pointer to an array of arrays is not a pointer to a pointer
to a pointer. A pointer to a pointer to a pointer and a pointer to an
array of arrays are not the same. A pointer to a pointer to a pointer
points at an object that points at an object that points. A pointer to
an array of arrays points at an object that contains a number of
consecutive elements of a type that contains a number of consecutive
elements of a type.
  A pointer to a pointer to a pointer to a pointer is not a pointer to
an array of arrays of arrays. A pointer to an array of arrays of
arrays is not a pointer to a pointer to a pointer to a pointer. A
pointer to a pointer to a pointer to a pointer and a pointer to an
array of arrays of arrays are not the same. A pointer to a pointer to
a pointer to a pointer points at an object that points at an object
that points at an object that points. A pointer to an array of arrays
of arrays points at an object that contains a number of consequtive
elements of a type that contains a number of consecutive elements of a
type that contains a number of consecutive elements of a type.
  Clear? (I hope I got all those "pointer to" and "arrays of" right.)

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?



Sun, 15 May 2005 07:31:29 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. Passing a char array[n] to a function expecting a char*

2. pass a pointer to array of structs to functions

3. passing array of pointers to function

4. Newbie question: Pointer to an array and passing it into a function

5. Passing 2-D pointer to array to function

6. Passing an array of pointers to functions

7. Simple, Pass Pointer of an Array to function

8. Not passing a value to a function when there is one expected

9. function pointers and function pointers array

10. Passing pointers to arrays of pointers....

11. Pointer to function passed to varargs function

12. Novice: Passing a function pointer to a function

 

 
Powered by phpBB® Forum Software