a question of style

Q

questions?

I am curious about whether I should do this

say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double result[4][4]){
blah blah

}

my results are automatically given back in the matrix result[4][4]

or

2)
double [4][4] dot_product(double A[4][4],double B[4][4]){
double result[4][4];
blah blah

return result;
}

for the second type, result is local variable and will be released
after function call, Will the program have problem to access?

Are there better and neat way to this problem?

Thanks
 
A

Artie Gold

questions? said:
I am curious about whether I should do this

say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double result[4][4]){
blah blah

}

my results are automatically given back in the matrix result[4][4]

or

2)
double [4][4] dot_product(double A[4][4],double B[4][4]){
double result[4][4];
blah blah

return result;
}

for the second type, result is local variable and will be released
after function call, Will the program have problem to access?

Are there better and neat way to this problem?

Thanks
Well since option 2 is not an option at all (arrays are not a first
class type in C, so an array cannot be a return value), you're left with
option 1.

The other option would be to wrap your array in a struct and return
*that*, but that would depend upon how you plan on using this code...

BTW - explicitly mentioning the first dimension of a passed array is
superfluous; i.e. `double A[][4]' and `double A[4][4]' -- or for that
matter double A[400][4] -- mean the same thing.

HTH,
--ag
 
Q

questions?

Artie said:
questions? said:
I am curious about whether I should do this

say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double result[4][4]){
blah blah

}

my results are automatically given back in the matrix result[4][4]

or

2)
double [4][4] dot_product(double A[4][4],double B[4][4]){
double result[4][4];
blah blah

return result;
}

for the second type, result is local variable and will be released
after function call, Will the program have problem to access?

Are there better and neat way to this problem?

Thanks
Well since option 2 is not an option at all (arrays are not a first
class type in C, so an array cannot be a return value), you're left with
option 1.

The other option would be to wrap your array in a struct and return
*that*, but that would depend upon how you plan on using this code...

BTW - explicitly mentioning the first dimension of a passed array is
superfluous; i.e. `double A[][4]' and `double A[4][4]' -- or for that
matter double A[400][4] -- mean the same thing.

I see, I see.
but Do you have the same problem?

Say you locally define a structure which has the array you want to
return.
when you return that, you are pointing to a local variable which will
be released?

Thanks a lot
 
A

Artie Gold

questions? said:
Artie said:
questions? said:
I am curious about whether I should do this

say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double result[4][4]){
blah blah

}

my results are automatically given back in the matrix result[4][4]

or

2)
double [4][4] dot_product(double A[4][4],double B[4][4]){
double result[4][4];
blah blah

return result;
}

for the second type, result is local variable and will be released
after function call, Will the program have problem to access?

Are there better and neat way to this problem?

Thanks

Well since option 2 is not an option at all (arrays are not a first
class type in C, so an array cannot be a return value), you're left with
option 1.

The other option would be to wrap your array in a struct and return
*that*, but that would depend upon how you plan on using this code...

BTW - explicitly mentioning the first dimension of a passed array is
superfluous; i.e. `double A[][4]' and `double A[4][4]' -- or for that
matter double A[400][4] -- mean the same thing.


I see, I see.
but Do you have the same problem?

Say you locally define a structure which has the array you want to
return.
when you return that, you are pointing to a local variable which will
be released?
No, you'd receive, as a return value, a *copy* of the local structure --
albeit a shallow copy.

HTH,
--ag
 
M

Micah Cowan

questions? said:
Artie said:
questions? said:
I am curious about whether I should do this

say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double result[4][4]){
blah blah

}

my results are automatically given back in the matrix result[4][4]

or

2)
double [4][4] dot_product(double A[4][4],double B[4][4]){
double result[4][4];
blah blah

return result;
}

for the second type, result is local variable and will be released
after function call, Will the program have problem to access?

Are there better and neat way to this problem?

Thanks
Well since option 2 is not an option at all (arrays are not a first
class type in C, so an array cannot be a return value), you're left with
option 1.

The other option would be to wrap your array in a struct and return
*that*, but that would depend upon how you plan on using this code...

BTW - explicitly mentioning the first dimension of a passed array is
superfluous; i.e. `double A[][4]' and `double A[4][4]' -- or for that
matter double A[400][4] -- mean the same thing.

I see, I see.
but Do you have the same problem?

Say you locally define a structure which has the array you want to
return.
when you return that, you are pointing to a local variable which will
be released?

Only if you return a /pointer/ to the struct. That's not what he's
recommending. He's saying, if you want, you can return the struct
itself. And he doesn't mean locally define the structure: it will have
to have a filescope definition, in order to declare it as the
function's return type.

Returning a struct involves an implicit copy of your local value
into a value that gets passed back to the caller as the return value.

-Micah
 
D

Default User

questions? said:
Artie said:
questions? said:
I am curious about whether I should do this

say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double
result[4][4]){ blah blah

}

my results are automatically given back in the matrix result[4][4]

or

2)
double [4][4] dot_product(double A[4][4],double B[4][4]){
double result[4][4];
blah blah

return result;
}

for the second type, result is local variable and will be released
after function call, Will the program have problem to access?

Are there better and neat way to this problem?

Thanks
Well since option 2 is not an option at all (arrays are not a first
class type in C, so an array cannot be a return value), you're left
with option 1.

The other option would be to wrap your array in a struct and return
that, but that would depend upon how you plan on using this code...

BTW - explicitly mentioning the first dimension of a passed array is
superfluous; i.e. `double A[][4]' and `double A[4][4]' -- or for
that matter double A[400][4] -- mean the same thing.

I see, I see.
but Do you have the same problem?

Say you locally define a structure which has the array you want to
return.
when you return that, you are pointing to a local variable which will
be released?

Only if you returned a pointer. With the struct variant, you return the
struct, so a copy is made of it. There's no pointer to a local variable
the way there can be with an array.


Brian
 
A

Andrey Tarasevich

questions? said:
I am curious about whether I should do this

say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double result[4][4]){
blah blah

}

my results are automatically given back in the matrix result[4][4]
...
Are there better and neat way to this problem?

Since both sizes of these arrays are fixed, when using this approach I'd declare
the function as follows

void dot_product(const double (*A)[4][4], const double (*B)[4][4],
double (*result)[4][4])
{
/* ... */
}

In my opinion, use of "decayed" pointers to pass arrays should be limited to
situations when array size is expected to vary.
 
P

Pedro Graca

Artie said:
questions? said:
Artie said:
questions? wrote:
[snip how to return an array]

The other option would be to wrap your array in a struct and return
*that*, but that would depend upon how you plan on using this code...

Say you locally define a structure which has the array you want to
return.
when you return that, you are pointing to a local variable which will
be released?
No, you'd receive, as a return value, a *copy* of the local structure --
albeit a shallow copy.

What do you mean with "a shallow copy"?

My test worked fine:


#include <stdio.h>

struct Arr {
int array[100];
};

struct Arr ret_struct(void) {
struct Arr foo = {{0}};
foo.array[0] = 1000;
foo.array[99] = 42;
return foo;
}

int main(void) {
struct Arr arr;

arr = ret_struct();
printf("%d, %d (repeated 98 times), %d\n",
arr.array[0], arr.array[50], arr.array[99]);
return 0;
}
 
K

Keith Thompson

Pedro Graca said:
Artie said:
questions? said:
Artie Gold wrote: [...]
The other option would be to wrap your array in a struct and return
*that*, but that would depend upon how you plan on using this code...

Say you locally define a structure which has the array you want to
return. when you return that, you are pointing to a local
variable which will be released?
No, you'd receive, as a return value, a *copy* of the local structure --
albeit a shallow copy.

What do you mean with "a shallow copy"?

If your structure contains pointers, the copy will contain copies of
those pointers (pointing to the same objects); any data outside the
structure itself won't be copied.

For example, suppose you have a struct representing a variable-length
string:

struct my_string {
size_t len;
char *str;
};

struct my_string s1, s2;
s1.len = 6;
s1.str = malloc(6); /* should check for errors here */
strcpy(s1.str, "hello");

Then this:

s2 = s1;

creates a shallow copy of s1. s1.str and s2.str point to the same
shared object; changing the string pointed to by s2.str will also
change the string pointed to by s1.str:

s2.str[0] = 'H';
/* now s1.str and s2.str both point to "Hello" */

By contrast, a deep copy creates a new copy of any pointed-to data
as well as of the structure itself:

s2.len = s1.len;
s2.str = malloc(s1.len); /* again, should check for error here */
memcpy(s2.str, s1.str, s1.len);

Now s1.str and s2.str point to distinct objects, and changing one
won't affect the other:

s2.str[0] = 'H';

/* now s2.str points to "Hello", but
s1.str still points to "hello" */

A deep copy requires knowing the contents of the structure. In more
complex cases, it may require recursing to other nodes (think about
making a deep copy of a binary tree).

Often a shallow copy is good enough -- which is fortunate, because a
deep copy requires substantially more work.
 
M

Micah Cowan

Pedro Graca said:
Artie said:
questions? said:
Artie Gold wrote:

questions? wrote:
[snip how to return an array]

The other option would be to wrap your array in a struct and return
*that*, but that would depend upon how you plan on using this code...

Say you locally define a structure which has the array you want to
return.
when you return that, you are pointing to a local variable which will
be released?
No, you'd receive, as a return value, a *copy* of the local structure --
albeit a shallow copy.

What do you mean with "a shallow copy"?

What he means is that if your struct has a pointer in it, that will be
copied over unchanged. So, for example:

#include <stdio.h>
#define ELMS_IN_ARY(a) (sizeof (a) / sizeof (a)[0])

struct foo {
int a[3];
char *b;
};

struct foo foo_maker(void)
{
char phrase[] = "D@mn it feels good to be a gangsta.";
struct foo retval = { {0, 1, 3}, phrase };

return retval;
}

int main(void)
{
struct foo doo;
int *cur, *end;

doo = foo_maker();
for (cur = &doo.a[0], end = cur + ELMS_IN_ARY(doo.a); cur != end; ++cur)
printf("%d\n", *cur);

printf("%s\n", doo.b);
return 0;
}

retval.a's elements will be copied into doo.a. However, the exact
pointer value contained in retval.b will also be copied over exactly
to doo.b, but after foo_maker() has exited, that value is invalid;
thus the second printf() statement in main() invokes undefined
behavior.

-Micah
 
P

Pedro Graca

Keith said:
If your structure contains pointers, the copy will contain copies of
those pointers (pointing to the same objects); any data outside the
structure itself won't be copied.
<snip>

Thank you very much for the excellent explanation -- I almost didn't
snip it: it deserves being repeated :).
 
T

Thad Smith

Andrey said:
questions? said:
say I want to calculate dot product of two matrix(4X4,fixed)
I do two ways

1)
void dot_product(double A[4][4] , double B[4][4], double result[4][4]){
blah blah

}

my results are automatically given back in the matrix result[4][4]
...
Are there better and neat way to this problem?

Since both sizes of these arrays are fixed, when using this approach I'd declare
the function as follows

void dot_product(const double (*A)[4][4], const double (*B)[4][4],
double (*result)[4][4])
{
/* ... */
}

Excellent suggestion!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,165
Latest member
JavierBrak
Top