Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Returning values passed from a function

0 views
Skip to first unread message

James

unread,
Apr 30, 2003, 11:26:24 AM4/30/03
to
This is a rather basic question but I thought i'd ask it anyway, since I
haven't yet learned about it in any of my books. Can a function return more
than one value to main, as in

return x,y ?

Thanks in advance.


Mark A. Odell

unread,
Apr 30, 2003, 11:44:21 AM4/30/03
to
"James" <James...@nyc.rr.com> wrote in
news:AWRra.28001$su3.3...@twister.nyc.rr.com:

No.

Mark A. Odell

unread,
Apr 30, 2003, 11:50:47 AM4/30/03
to
"Mark A. Odell" <nos...@embeddedfw.com> wrote in
news:Xns936D776B05A35lk...@130.133.1.4:

Maybe I could be more verbose, you can return whatever you want as long as
it is a single type, e.g. you could return many things inside a struct or
pointed to by a pointer.


struct Thing
{
int apple;
double butter;
char tree[1024];
};

struct Thing fillInThing(void)
{
struct Thing out;
out.apple = 12;
out.butter = 3.141592;
strcpy(tree, "hello world");

return out;
}

int main(void)
{
struct Thing thing = fillInThing();
return 0;
}


Note that one would typically pass a pointer to the struct to
fillInThing() and have fillInThing() fill it in in situ and then return
status of the fill process if desireable. The code above may not be ver
efficient since the struct is passed "by value" to borrow a phrase so the
C run-time must copy the value from the callee back to the caller, main().

Lew Pitcher

unread,
Apr 30, 2003, 11:38:55 AM4/30/03
to
James wrote:
> This is a rather basic question but I thought i'd ask it anyway, since I
> haven't yet learned about it in any of my books. Can a function return more
> than one value to main, as in

No, although there are various "coding tricks" that would permit a
function to effectively return multiple values. (I'm thinking
specifically of the function returning a structure, which has more than
one element, and thus more than one value.)


> return x,y ?

As it stands
return x,y;
will return y only to the caller (it's the "comma operator", doncha know).

--
Lew Pitcher, IT Consultant, Application Architecture
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)

Joona I Palaste

unread,
Apr 30, 2003, 11:55:37 AM4/30/03
to
Mark A. Odell <nos...@embeddedfw.com> scribbled the following:

> No.

You might want to try a language with polymorphic type inference, such
as ML or Haskell. In such languages, any combination of any type is a
type too. For example, Integer is a type, and so are (Integer, Integer),
(Integer, Integer, Integer) and even ((Integer, Integer), Integer).

--
/-- Joona Palaste (pal...@cc.helsinki.fi) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"How can we possibly use sex to get what we want? Sex IS what we want."
- Dr. Frasier Crane

Mike Wahler

unread,
Apr 30, 2003, 12:07:13 PM4/30/03
to

James <James...@nyc.rr.com> wrote in message
news:AWRra.28001$su3.3...@twister.nyc.rr.com...

> This is a rather basic question but I thought i'd ask it anyway, since I
> haven't yet learned about it in any of my books. Can a function return
more
> than one value to main,

No.

> as in
>
> return x,y ?

The expression x,y yields the value of 'y',
so this statement returns the value of 'y'.

You *can* have a function modify some or all of
its caller's arguments by passing pointers to
them:

#include <stdio.h>

int foo(int *parm)
{
*parm = 42;
return 99;
}

int main()
{
int i = 0;
int j = 1;

printf("Before calling function foo():\n"
"i == %d, j == %d\n", i, j);

i = foo(&j);

putchar('\n');

printf("After calling function foo():\n"
"i == %d, j == %d\n", i, j);

return 0;
}


Another possiblity is to define a struct (which
can contain many values) for your function's
return type.

#include <stdio.h>

struct x
{
int a;
int b;
int c;
};

struct x foo(void)
{
struct x temp;
temp.a = 1;
temp.b = 2;
temp.c = 3;
return temp;
}

int main()
{
struct x result = foo();

printf("result.a == %d\n"
"result.b == %d\n"
"result.c == %d\n",
result.a, result.b, result.c);

return 0;
}

-Mike

Thomas Matthews

unread,
Apr 30, 2003, 12:01:18 PM4/30/03
to

No.
However, you can create a structure containing two values
and return the structure:
typedef struct {
int x;
int y;
} Point;

Point Center()
{
Point new_point;
new_point.x = 4;
new_point.y = 5;
return Point;
}


--
Thomas Matthews

C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq: http://www.raos.demon.uk/acllc-c++/faq.html

Dan Pop

unread,
Apr 30, 2003, 12:13:17 PM4/30/03
to

>"Mark A. Odell" <nos...@embeddedfw.com> wrote in
>news:Xns936D776B05A35lk...@130.133.1.4:
>
>> "James" <James...@nyc.rr.com> wrote in
>> news:AWRra.28001$su3.3...@twister.nyc.rr.com:
>>
>>> This is a rather basic question but I thought i'd ask it anyway, since
>>> I haven't yet learned about it in any of my books. Can a function
>>> return more than one value to main, as in
>>>
>>> return x,y ?

That would return exactly one value, y. This is how the comma operator
works.

>>
>> No.
>
>Maybe I could be more verbose, you can return whatever you want as long as
>it is a single type, e.g. you could return many things inside a struct or
>pointed to by a pointer.
>
>
>struct Thing
>{
> int apple;
> double butter;
> char tree[1024];
>};
>
>struct Thing fillInThing(void)
>{
> struct Thing out;
> out.apple = 12;
> out.butter = 3.141592;
> strcpy(tree, "hello world");

^^^^
That's supposed to be out.tree.

> return out;
>}
>
>int main(void)
>{
> struct Thing thing = fillInThing();
> return 0;
>}
>
>
>Note that one would typically pass a pointer to the struct to
>fillInThing() and have fillInThing() fill it in in situ and then return
>status of the fill process if desireable. The code above may not be ver
>efficient since the struct is passed "by value" to borrow a phrase so the
>C run-time must copy the value from the callee back to the caller, main().

This is true for large structures, like yours. However, when the
structure only consists of a few scalars, "passing by value" is usually
cleaner than "passing by address" (the pedants are advised to pay
attention to the double quotes before "teaching" me that there is no
pass by address in C).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan...@ifh.de

Dan Pop

unread,
Apr 30, 2003, 1:18:21 PM4/30/03
to
In <b8orlp$dpo$2...@oravannahka.helsinki.fi> Joona I Palaste <pal...@cc.helsinki.fi> writes:

>Mark A. Odell <nos...@embeddedfw.com> scribbled the following:
>> "James" <James...@nyc.rr.com> wrote in
>> news:AWRra.28001$su3.3...@twister.nyc.rr.com:
>>> This is a rather basic question but I thought i'd ask it anyway, since I
>>> haven't yet learned about it in any of my books. Can a function return
>>> more than one value to main, as in
>>>
>>> return x,y ?
>
>> No.
>
>You might want to try a language with polymorphic type inference, such
>as ML or Haskell. In such languages, any combination of any type is a
>type too. For example, Integer is a type, and so are (Integer, Integer),
>(Integer, Integer, Integer) and even ((Integer, Integer), Integer).

How is this any different from C's structures?

Joona I Palaste

unread,
Apr 30, 2003, 2:24:37 PM4/30/03
to
Dan Pop <Dan...@cern.ch> scribbled the following:

First, combination types don't need to be named or even defined, simply
writing out the combination as above will do. For example, if C worked
like ML or Haskell, you wouldn't need to do:

struct mystruct {
int a;
int b;
};
struct mystruct m;

You could just do:

(int, int) m;

Second, there are type variables, which can stand for any type, and
you can even build combinations of type variables. For example, in
increasing order of specificity:

a
(a, b)
(Integer, b)
(Integer, Integer)

E. Robert Tisdale

unread,
Apr 30, 2003, 3:08:56 PM4/30/03
to
James wrote:

> Can a function return more than one value to main?

typedef struct intPair {
int x, y;
} intPair;

intPair f(void) {
intPair p = {1, 2};
return p;
}

kh...@khabs.de

unread,
Apr 30, 2003, 4:18:42 PM4/30/03
to
The trouble is : sex is not numeric!
khabs

Emmanuel Delahaye

unread,
May 1, 2003, 6:30:02 AM5/1/03
to

No. The usual trick is to pass the address of a structure to a function

typedef struct
{
int x;
float y;
}
results_s;

...
{
results_s res;

err = f (&res);

if (!err)
{
...
}
}


int f (results_s *const p_res)
{
...

if (p_res)
{
p_res->x = foo;
p_res->y = bar;
}

return err;
}

--
-ed- emdel at noos.fr
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-library: http://www.dinkumware.com/htm_cl/index.html
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Emmanuel Delahaye

unread,
May 1, 2003, 6:33:55 AM5/1/03
to

Note that this trick is not recommended with objetcs bigger than, say , an
unsigned long.

Prefer to pass the address of a structure.

E. Robert Tisdale

unread,
May 1, 2003, 4:17:35 PM5/1/03
to
Emmanuel Delahaye wrote:

> E. Robert Tisdale wrote:
>
>>James wrote:
>>
>>>Can a function return more than one value to main?
>>
>> typedef struct intPair {
>> int x, y;
>> } intPair;
>>
>> intPair f(void) {
>> intPair p = {1, 2};
>> return p;
>> }
>
> Note that this trick is not recommended

> with objects bigger than, say, an unsigned long.

Nonsense!

> Prefer to pass the address of a structure.

You are blithering.

Regardless of size, you should return the object by value.
Let your optimizing C compiler decide whether or not
it should pass an address to the return value.

Alex

unread,
May 1, 2003, 5:17:38 PM5/1/03
to
E. Robert Tisdale <E.Robert...@jpl.nasa.gov> wrote:
> Emmanuel Delahaye wrote:

>> E. Robert Tisdale wrote:
>>
>>>James wrote:
>>>
>>>>Can a function return more than one value to main?
>>>
>>> typedef struct intPair {
>>> int x, y;
>>> } intPair;
>>>
>>> intPair f(void) {
>>> intPair p = {1, 2};
>>> return p;
>>> }
>>
>> Note that this trick is not recommended
>> with objects bigger than, say, an unsigned long.

> Nonsense!

Over-generalization but not nonsense.

>> Prefer to pass the address of a structure.

> You are blithering.

> Regardless of size, you should return the object by value.
> Let your optimizing C compiler decide whether or not

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> it should pass an address to the return value.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Ummm? Are you saying that the compiler will magically change

intPair f(void)
{
intPair p = {1, 2};
return p;
}

void foo(void)
{
intPair rc = f();
printf("x = %d, y = %d\n", rc.x, rc.y);
}

to
intPair *f(void)
{
intPair *p = malloc(sizeof *p);

p->x = 1;
p->y = 2;

return p;
}

void foo(void)
{
intPair *rc = f();

printf("x = %d, y = %d\n", rc->x, rc->y);

free(rc);
}

?

E. Robert Tisdale

unread,
May 1, 2003, 6:00:02 PM5/1/03
to
Alex wrote:

> Ummm? Are you saying that the compiler will magically change
>
> intPair f(void) {
> intPair p = {1, 2};
> return p;
> }
>
> void foo(void) {
> intPair rc = f();
> printf("x = %d, y = %d\n", rc.x, rc.y);
> }
>
> to

> intPair*f (intPair* p) {


>
> p->x = 1;
> p->y = 2;
>
> return p;
> }
>
> void foo(void) {

> intPair rc;
> f(&rc);


> printf("x = %d, y = %d\n", rc.x, rc.y);
>
> }


$ cat intPair.c


typedef struct intPair {
int x, y;
} intPair;

intPair f(void) {
intPair p = {1, 2};
return p;
}

void foo(void) {
intPair rc = f();
}

$ gcc -Wall -ansi -pedantic -O2 -S intPair.c
intPair.c: In function `foo':
intPair.c:11: warning: unused variable `rc'
$ expand intPair.s
.file "intPair.c"
.text
.align 2
.p2align 2,,3
.globl f
.type f,@function
f:
pushl %ebp // save old frame pointer
movl %esp, %ebp // init new frame pointer
movl 8(%ebp), %eax // &rc
movl $1, %edx
movl $2, %ecx
movl %edx, (%eax) // rc.x <-- 1
movl %ecx, 4(%eax) // rc.y <-- 2
leave // restore frame pointer
ret $4
.Lfe1:
.size f,.Lfe1-f
.align 2
.p2align 2,,3
.globl foo
.type foo,@function
foo:
pushl %ebp // save frame pointer
movl %esp, %ebp // init new frame pointer
leal -8(%ebp), %eax // &rc
subl $20, %esp // allocate automatic storage
pushl %eax // push &rc
call f
leave // restore frame pointer
ret
.Lfe2:
.size foo,.Lfe2-foo
.ident "GCC: (GNU) 3.2 20020903 \
(Red Hat Linux 8.0 3.2-7)"

It isn't "magic".
It's just an optimization performed by your compiler.

Dan Pop

unread,
May 2, 2003, 9:27:03 AM5/2/03
to

So, no difference in functionality up to now...

>Second, there are type variables, which can stand for any type, and
>you can even build combinations of type variables. For example, in
>increasing order of specificity:
>
>a
>(a, b)
>(Integer, b)
>(Integer, Integer)

What's the purpose of a variable, if you don't know its type?

Joona I Palaste

unread,
May 2, 2003, 9:51:22 AM5/2/03
to
Dan Pop <Dan...@cern.ch> scribbled the following:
> In <b8p4d5$h3c$1...@oravannahka.helsinki.fi> Joona I Palaste <pal...@cc.helsinki.fi> writes:

(Differences between ML and Haskell and C)

>>Second, there are type variables, which can stand for any type, and
>>you can even build combinations of type variables. For example, in
>>increasing order of specificity:
>>
>>a
>>(a, b)
>>(Integer, b)
>>(Integer, Integer)

> What's the purpose of a variable, if you don't know its type?

Polymorphic functions, i.e. functions whose parameters are of
polymorphic type.

For example, a function to swap the elements of a combined type around:

swap :: (a, b) -> (b, a) -- equivalent to C's function prototype
swap (x, y) = (y, x) -- equivalent to C's function body

This works for *any* combined type which is the combination of *any*
two types. The types can even be combined types themselves. For example,
if m is of type (Integer, Char) and has the value of (1, 'a') then
swap m is of type (Char, Integer) and has the value of ('a', 1).
How would you write this in C then?

--
/-- Joona Palaste (pal...@cc.helsinki.fi) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/

"Stronger, no. More seductive, cunning, crunchier the Dark Side is."
- Mika P. Nieminen

Tak-Shing Chan

unread,
May 2, 2003, 11:28:54 AM5/2/03
to
On 2 May 2003, Joona I Palaste wrote:

> swap :: (a, b) -> (b, a) -- equivalent to C's function prototype
> swap (x, y) = (y, x) -- equivalent to C's function body
>
> This works for *any* combined type which is the combination of *any*
> two types. The types can even be combined types themselves. For example,
> if m is of type (Integer, Char) and has the value of (1, 'a') then
> swap m is of type (Char, Integer) and has the value of ('a', 1).
> How would you write this in C then?

This could be written in C if you encapsulate all relevant
types within a single tree node:

struct tree *swap(struct tree *a, struct tree *b) {
return merge(b, a);
}

Tak-Shing

Dan Pop

unread,
May 2, 2003, 12:12:16 PM5/2/03
to
In <b8tt4q$hgk$1...@oravannahka.helsinki.fi> Joona I Palaste <pal...@cc.helsinki.fi> writes:

>Dan Pop <Dan...@cern.ch> scribbled the following:
>> In <b8p4d5$h3c$1...@oravannahka.helsinki.fi> Joona I Palaste <pal...@cc.helsinki.fi> writes:
>
>(Differences between ML and Haskell and C)
>
>>>Second, there are type variables, which can stand for any type, and
>>>you can even build combinations of type variables. For example, in
>>>increasing order of specificity:
>>>
>>>a
>>>(a, b)
>>>(Integer, b)
>>>(Integer, Integer)
>
>> What's the purpose of a variable, if you don't know its type?
>
>Polymorphic functions, i.e. functions whose parameters are of
>polymorphic type.

How do you use them for non-trivial purposes, if you don't know their
types?

>For example, a function to swap the elements of a combined type around:
>
>swap :: (a, b) -> (b, a) -- equivalent to C's function prototype
>swap (x, y) = (y, x) -- equivalent to C's function body
>
>This works for *any* combined type which is the combination of *any*
>two types. The types can even be combined types themselves. For example,
>if m is of type (Integer, Char) and has the value of (1, 'a') then
>swap m is of type (Char, Integer) and has the value of ('a', 1).
>How would you write this in C then?

Why would you want to code this insanity in C? ;-)

0 new messages