Board index » cppbuilder » Function call.

Function call.


2008-04-07 12:06:18 PM
cppbuilder67
Hello,
I have a function call which will not compile. The problem arises,
out of calling a function with two dimensional matrixs as parameters.
The code looks like this;
the .h file;
void __fastcall Linear(TObject *Sender, double *a, int n,
double *x, int er);
the .cpp file;
int msize, er;
double gam[102][103], aw[102];
(1711) Linear(Sender, gam, msize + 1, aw, er);
the function;
void __fastcall TSMODForm::Linear(TObject *Sender, double *a,
int n, double *x, int er)
{
double a[102][103], x[102];
int n, er;
}
The compile error;
[C++ Error] GeosMOD.cpp(1711): E2034 Cannot convert 'double ( *)[103]' to
'double *'
[C++ Error] GeosMOD.cpp(1711): E2342 Type mismatch in parameter 'a' (wanted
'double *', got 'double ( *)[103]')
How do I pass a two dimensional matrix in a function call?
 
 

Re:Function call.

Digby Millikan wrote:
Quote
How do I pass a two dimensional matrix in a function call?


void func( double * a [103] )
or
void func( double **a );
 

Re:Function call.

On Sun, 06 Apr 2008 22:55:33 -0700, "Alex Bakaev [TeamB]"
< XXXX@XXXXX.COM >wrote:
Quote
Digby Millikan wrote:

>How do I pass a two dimensional matrix in a function call?
>
>
void func( double * a [103] )

or
void func( double **a );
--valid only on C++ --
or:
void func( double *(&a) [103] )
or:
void func( double (&a)[102] [103] )
 

{smallsort}

Re:Function call.

"Alex Bakaev [TeamB]" < XXXX@XXXXX.COM >wrote:
Quote
void func( double * a [103] )

or
void func( double **a );
Neither will compile. Only this compiles:
void func( double (* a) [103] )
By the way, is the matrix really of fixed dimension 102 x 103?
Vaclav
 

Re:Function call.

"Digby Millikan" < XXXX@XXXXX.COM >wrote in message
Quote
void __fastcall Linear(TObject *Sender, double *a, int n,
double *x, int er);
...
double gam[102][103], aw[102];

(1711) Linear(Sender, gam, msize + 1, aw, er);
...
How do I pass a two dimensional matrix in a function call?
If Linear really wants a pointer to double then call Linear this way:
Linear(Sender, *gam, msize + 1, aw, er);
HTH,
Clayton
 

Re:Function call.

Vaclav Cechura wrote:
Quote

Neither will compile. Only this compiles:

Indeed. I should've tried before posting :)
 

Re:Function call.

Clayton Arends wrote:
Quote
"Digby Millikan" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>void __fastcall Linear(TObject *Sender, double *a, int
>n, double *x, int er);
...
>double gam[102][103], aw[102];
>
>(1711) Linear(Sender, gam, msize + 1, aw, er);
...
>How do I pass a two dimensional matrix in a function call?

If Linear really wants a pointer to double then call Linear this way:

Linear(Sender, *gam, msize + 1, aw, er);

I think you mean & not *,
Linear(Sender, &gam, msize + 1, aw, er);
but I suspect it may have the same problem with the type information.
This should be equivalent, and it will definitely have the correct type.
Linear(Sender, &gam[0][0], msize + 1, aw, er);
HTH
Dennis Cote
 

Re:Function call.

"Dennis Cote" < XXXX@XXXXX.COM >wrote in message
Quote
>If Linear really wants a pointer to double then call Linear this way:
>
>Linear(Sender, *gam, msize + 1, aw, er);
>

I think you mean & not *,

Linear(Sender, &gam, msize + 1, aw, er);
No, I meant "*". "&gam" would be a pointer to a 2 dimension array of
doubles (which is going the wrong direction). "*gam" is a more efficient
notation for "gam[0]" (depending upon the optimizer used) since "gam[0]"
requires an indexed lookup.
Quote
Linear(Sender, &gam[0][0], msize + 1, aw, er);
"&gam[0][0]" is the same as "gam[0]" which is the same as "*gam"
Clayton
 

Re:Function call.

"Clayton Arends" < XXXX@XXXXX.COM >writes:
Quote
"&gam[0][0]" is the same as "gam[0]" which is the same as "*gam"
Address-wise, yes, but type-wise, no.
(&gam[0][0] results in a pointer type. The other two result in an
array type.)
--
Chris (TeamB);
 

Re:Function call.

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
Address-wise, yes, but type-wise, no.
My point was that they can all be used to get the same result. The C/C++
compiler will implicitly convert an array type to its pointer counterpart
(which you know).
Clayton
 

Re:Function call.

"Clayton Arends" < XXXX@XXXXX.COM >writes:
Quote
"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>Address-wise, yes, but type-wise, no.

My point was that they can all be used to get the same result. The
C/C++ compiler will implicitly convert an array type to its pointer
counterpart (which you know).
Yes, but the fine-line between a pointer and array is lost to many,
and it's worthwhile (IMHO) to show a difference when it's clearly
visible.
There are cases where it's critically important to keep the types
exactly the same, so it pays to mentally treat them as distinctly
different types (since they are) and apply the conversion rules in
your head everywhere they occur. One really subtle and {*word*193} example
where getting sloppy between types can really bite you: if you define
a global array in one file, and you extern declare it as a pointer in
another, then index into the array through that pointer, boom. REALLY
bad things happen, as the pointer is thought to hold "just" an
address, but in reality the pointer's bits are the beginning of the
actual array data. When the pointer is used, the first 4 bytes at the
beginning of the array are thought to be the address of the data, and
so it converts the first bytes of the array elements into an address,
jumps to THAT address and reads. I think Stephen Dewhurst even put
this in his C++ Gotchas book. (Which is a very good book.)
--
Chris (TeamB);
 

Re:Function call.

Hello,
Yes the array is really fixed dimension, I changed the function call,
which is compiling.
the .h file;
void __fastcall Linear(TObject *Sender, double *a, int n,
double *x, int er);
the .cpp file;
int msize, er;
double gam[102][103], aw[102];
Linear(Sender, *gam, msize + 1, aw, er);
the function;
void __fastcall TSMODForm::Linear(TObject *Sender, double *a,
int n, double *x, int er)
{
(1981) if( a[j][i] != 0.0) {
}
}
The compile error;
[C++ Error] GeosMOD.cpp(1981): E2062 Invalid indirection
The two dimensional array seems not to be declared within the function.
Where are the
errors in my code? Is my function and array declaration incorrect? Can I
keep the array
declared as two dimensional and pass it in a function call?
 

Re:Function call.

Digby Millikan wrote:
Quote
double gam[102][103], aw[102];
Linear(Sender, *gam, msize + 1, aw, er);

void __fastcall TSMODForm::Linear(TObject *Sender, double *a, int n, double *x, int er)
{
if( a[j][i] != 0.0)
The two dimensional array seems not to be declared within the function.
Where are the errors in my code?
Linear has no idea what the column dimension is,
so it has no way to calculate [j][i].
Quote
Can I keep the array
declared as two dimensional and pass it in a function call?
At least 2 options:
Simple:
if( a[(j*103)+i] != 0.0) {
Not-so-simple:
struct dbl_102x103{
double second[102][103];
};
double _stdcall f(struct dbl_102x103*first, int i, int j)
{
return first->second[i][j];
}
int main (void)
{
double a[102][103] = {{1,2,3,4,5},{11,12,13,14,15},{21,22,23,24,25}};
printf( "\nf = %f\n", f(a,2,3)); // prints 24.0
 

Re:Function call.

"Digby Millikan" < XXXX@XXXXX.COM >writes:
Quote
Hello,

Yes the array is really fixed dimension, I changed the function call,
which is compiling.
You'd be MUCH better off declaring a symbolic constant for the sizes,
and using that. Given a name instead of hard-coding the size, you're
safer in that
1) code consistently use the same size. (No accidental typos in some
places causing subtle bugs.)
2) other programmers don't have to ask "Is that value really fixed
size?" since the code tells them.
3) you can change the size in one place and have it updated
"everywhere"
Quote
void __fastcall TSMODForm::Linear(TObject *Sender, double *a,
int n, double *x, int er)
{

(1981) if( a[j][i] != 0.0) {
When you have a pointer to double, such as "double *a", when you index
into it a[j] the return type is double, not array. It's an element.
You therefore must treat "a" as a single array that is "really long"
and adjust your offset as if it were a 2d access (j*rowsize + column)
or else change the type of a to be an array of arrays in the function
declaration. (The outermost array decays to pointer, but the inner
ones do not.)
void __fastcall TSMODForm::Linear(
TObject *Sender, double a[ROWWIDTH][ROWS], int n, double *x, int er)
Then you can index into a with 2 applications of the indexing operator:
if( a[j][i] != 0.0) { ... }
(a is really a pointer to an array, but you can do pointer arithmetic
to get "other" arrays to which it points, making the illusion of a 2d
array.)
--
Chris (TeamB);