Page 1 of 2
functions returning multiple variables (C/C++)
Posted: Mon Jan 07, 2008 7:50 am
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:
Posted: Mon Jan 07, 2008 11:35 am
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++.
Posted: Mon Jan 07, 2008 10:45 pm
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.
Posted: Tue Jan 08, 2008 2:18 am
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...
Posted: Tue Jan 08, 2008 6:32 pm
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.
Posted: Sat Jan 12, 2008 12:45 am
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);
}
Posted: Sat Jan 12, 2008 4:07 am
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
Posted: Sat Jan 12, 2008 5:40 am
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 *)),...
Posted: Sat Jan 12, 2008 6:26 am
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
c.f. Perl - returning arrays/tuples is a bloody gem of a language trait.
Posted: Sat Jan 12, 2008 4:30 pm
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...
Posted: Mon Jan 14, 2008 7:40 am
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"...
Posted: Tue Jan 15, 2008 12:10 am
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".
Posted: Tue Jan 15, 2008 8:56 am
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.
Posted: Tue Jan 15, 2008 10:02 am
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.
I havent seen anything like this before
Posted: Tue Jan 15, 2008 10:10 am
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 ...
This post is very interesting ... Is it compiler specific
I definitely have no clue