functions returning multiple variables (C/C++)

Programming, for all ages and all languages.
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

functions returning multiple variables (C/C++)

Post by AndrewAPrice »

I came up with a quick idea (not to be taken seriously) for C/C++ and how you could return multiple variables with one function.

Code: Select all

#include <iostream>

int, int, int, Example()
{
	return 3, 2, 1;
}


int main()
{
	int a, b, c;

	a, b, c = Example();

	std::cout << "a: " << a << " b: " << b << " c: " << c << std::endl;

	return 0;
}
The output would be:

Code: Select all

a: 3 b: 2 c: 1
My OS is Perception.
User avatar
bluecode
Member
Member
Posts: 202
Joined: Wed Nov 17, 2004 12:00 am
Location: Germany
Contact:

Post by bluecode »

std::pair in <utility>
std::tr1::tuple in <tr1/tuple> (Technical Report 1), which will be in the C++0x standard as std::tuple in <tuple>

About your suggestion: , is already used as an operator in C/C++.
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

Need multiple return value? Why not use reference parameters. Myself i allways tend to use

Code: Select all

int func(int & ref1, int & ref2, int & ref3);
Which returns a status
I understand that you want it in a readable form but having more then one method of doing stuff tends to lead to more confusion.
Author of COBOS
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

os64dev wrote:Need multiple return value? Why not use reference parameters. Myself i allways tend to use

Code: Select all

int func(int & ref1, int & ref2, int & ref3);
...which wouldn't survive a code review here. Reference parameters in themselves are bad enough; if you use them, at least make the function a void one so you don't "return" values in two different ways...
Every good solution is obvious once you've found it.
User avatar
Telgin
Member
Member
Posts: 72
Joined: Thu Dec 20, 2007 1:45 pm

Post by Telgin »

os64dev wrote:Need multiple return value? Why not use reference parameters. Myself i allways tend to use

Code: Select all

int func(int & ref1, int & ref2, int & ref3);
Which returns a status
I understand that you want it in a readable form but having more then one method of doing stuff tends to lead to more confusion.
I tend to fall back on this too when I need to.

Of course, another simple method is to simply return a struct that is filled out in the function. This only makes design sense if the struct would be used in more than one place, and it could logically be filled out by the function though.

As far as your code example goes, it does seem logical, but the syntax would be a little confusing for the compiler.

For instance,

a, b, c = foo();

This is a little tricky, because I think C/C++ interprets this as three separate declarations / statements, and would only try to work out c = foo();


Nothing preventing a revision of the syntax to work around this tough.
User avatar
AndrewAPrice
Member
Member
Posts: 2299
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

Telgin wrote:a, b, c = foo();

This is a little tricky, because I think C/C++ interprets this as three separate declarations / statements, and would only try to work out c = foo();
How about
(a, b, c) = foo();

and in foo():

(int, int, int) foo()
{
return (0, 1, 2);
}
My OS is Perception.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Post by distantvoices »

Hmmm ...

ain't sure if that works.
I'd rather reckon that the compiler 'd bork on that.

Better you return a structure. they get copied over to the caller upon return in case you don't use a pointer.

stay safe
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
User avatar
binutils
Member
Member
Posts: 214
Joined: Thu Apr 05, 2007 6:07 am

Post by binutils »

distantvoices wrote: Better you return a structure.
I will second that.

or/with you can take structure as function's parameter.
or/with function pointer.

Code: Select all

void f(struct a), struct f(struct * a), void f(struct *a), void f(void (*fp) (struct *)),...
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

MessiahAndrw wrote:
Telgin wrote:a, b, c = foo();

This is a little tricky, because I think C/C++ interprets this as three separate declarations / statements, and would only try to work out c = foo();
How about
(a, b, c) = foo();

and in foo():

(int, int, int) foo()
{
return (0, 1, 2);
}
I would love to see this implemented on GCC :D

c.f. Perl - returning arrays/tuples is a bloody gem of a language trait.
User avatar
Telgin
Member
Member
Posts: 72
Joined: Thu Dec 20, 2007 1:45 pm

Post by Telgin »

MessiahAndrw wrote:
Telgin wrote:a, b, c = foo();

This is a little tricky, because I think C/C++ interprets this as three separate declarations / statements, and would only try to work out c = foo();
How about
(a, b, c) = foo();

and in foo():

(int, int, int) foo()
{
return (0, 1, 2);
}
Yeah, I'd say that's clearer. I'd sort of like to see something like this implemented into the core language of C/C++, but in reality I've only seen a few times where I really would have needed.

Then again, there are other things even less needed or are more confusing. Multiple inheiretance for instance...
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Telgin wrote:I'd sort of like to see something like this implemented into the core language of C/C++...
Won't happen, as the statement already is legal (if somewhat nonsensical) C code, which would silently change its meaning if you'd extend the language in this way. Silent changes to perfectly good code are among the last things the standard committees will consider. Especially since there are two accepted canon methods to do what you want - returning a structure, and using reference parameters.
Then again, there are other things even less needed or are more confusing. Multiple inheiretance for instance...
Java uses two different kinds of inheritance, distinguishing between base classes and interfaces. In C++, you can use pure virtual base classes to achieve exactly the same effect.

Keep in mind that C++ inherited more from C than just general syntax. It also inherited the approach that "the programmer knows what he's doing, so get out of the way"...
Every good solution is obvious once you've found it.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Post by Colonel Kernel »

Just a nitpick -- MI is not inherently bad. It's the implementation of MI in C++ with all the sharp daggers that it introduces (diamond problem, casting moving pointers around unexpectedly, objects getting a lot of vptrs, etc.) that leads many to recommend against its use.

If you use templates in C++, you can achieve the same effect as MI much more safely using the "mixin" technique:

Code: Select all

template <class Base>
class FooBase : public Base { ... };

template <class Base>
class BarBase : public Base { ... };

class UltimateBase { ... };

class Derived : public BarBase< FooBase< UltimateBase > > { ... };
This has saved me from the dreaded "diamond" pattern many times. Scala actually formalizes this kind of inheritance and achieves it without the use of templates -- they call it "traits".
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
binutils
Member
Member
Posts: 214
Joined: Thu Apr 05, 2007 6:07 am

Post by binutils »

Just curiosity, why need MI or anything in c++?
I for one who very welcome to use c++ library like boost, but no thanks to c++ syntatic sugar at all.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Colonel Kernel wrote:If you use templates in C++, you can achieve the same effect as MI much more safely using the "mixin" technique...
Erm... which achieves what, exactly? I mean, aside from making a total mess of what should be an inheritance graph, scaring the majority of C++ coders (who didn't really grasp templates even after all those years) witless, and turning it into something butt-ugly? (Not that the rest of C++ actually smells of roses. I) )
This has saved me from the dreaded "diamond" pattern many times.
Most of the problems involved in a "diamond pattern" can be solved by a) proper design, and / or b) public virtual inheritance.

Check out the C++ FAQ Lite on multiple inheritance.
Every good solution is obvious once you've found it.
DeletedAccount
Member
Member
Posts: 566
Joined: Tue Jun 20, 2006 9:17 am

I havent seen anything like this before

Post by DeletedAccount »

Well .. I havent seen anything like this in C/ C++ .. May be using these constructs will lead to more confusion ... I have definitely not read such a thing in White Book or any other reference book which I have ... It seems to be Pythonish .. not at all Cish ...

:P This post is very interesting ... Is it compiler specific :?: I definitely have no clue
Post Reply