Is it possible to return multiple values from a function?
ex.
or something like that?Code:char such(void) { stuff return a; return b; } int main() { c,d = such(); }
Is it possible to return multiple values from a function?
ex.
or something like that?Code:char such(void) { stuff return a; return b; } int main() { c,d = such(); }
The only way to do that would be a struct or just passing the variables by reference:
Code:void foo( char &a, char &b ) { stuff; a = value; b = value2; } int main( void ) { int a, b; foo( a, b ); }
Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah
You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie
There are ways to return multiple values from a function, but you can't do it in a return statement. How are you with arrays? Try this:
Code:#include <iostream> using namespace std; void func(double number[]) { number[0] = 20.0; number[1] = 30.0; } int main() { double data[2]; data[0] = 6.0; data[1] = 7.0; func(data); cout<<data[0]<<endl<<data[1]<<endl; return 0; }
Last edited by 7stud; 07-31-2003 at 11:25 PM.
For this to work you'd still need to pass by ref.
Code:void func(double &number[])
hsv,
Try again.
There is a way to return multiple values but I do not recommend doing this.
In C and on x86 platforms the C compiler looks at the (e)ax register for integral return values and at st(0) for floating point returns.
It is possible to simply place values in registers to return multiple values.
Even though this is void, we know this function returns a value - not a good practice at all because it obfuscates the purpose of the function and violates several rules of C programming. But in theory it is the same as placing a return type in front of the function name - EXCEPT that the compiler will not be able to do MyVar=MyFoo(a,b,c,d) - because you declared MyFoo as void so the compiler says - hey you dummy you can't return a value from a void function. Even though you have placed your value in (e)ax the compiler does not know this and so will yell at you all day long.Code:void ReturnFoo(int a,int b,int c,int d) { _AX=a+b; _BX=c+d; }
or
This code notifies the C compiler that an integral value will be returned - so it places the result of a+b into (e)ax. So when you do MyVar=MyFoo(a,b,c,d) the compiler knows upon returning from MyFoo it should look in (e)ax for the value and place that into the memory location or variable known as MyVar. Everybody gets along this way and this is the correct prototype.Code:int ReturnFoo(int a,int b,int c,int d) { _BX=c+d; return (a+b); }
Nearly the same as the following asm code. I say nearly because in the disassembly you will not see ARG and you will not see the variable names - you will see stack locations.
However there are better ways to do this as have been described in this thread. Usually returning a pointer to a structure is the best way to do it. C is not really returning an array, but a pointer to an array - the pointer resides in (e)ax - even for floating point arrays.Code:_ReturnFoo proc ARG a:WORD,b:WORD,c:WORD,d:WORD push bp mov bp,sp mov bx,[c] add bx,[d] mov ax,[a] add ax,[b] pop bp ret _ReturnFoo endp
But the reason that my example will work is because the registers are not on the stack, so you can set their value and when your function returns to the caller - the registers should theoretically hold the value you placed in them, unless C has done something else with those registers. But I seriously doubt that C would mess with the explicit return registers after returning from a function. We know for sure that C does nothing with (e)ax and st(0) or else we could not return values from functions - so logically we could say that C also will not alter any other explicit return value registers or floating point registers. However I would not return values in any other registers because you will run into trouble.
The only thing that is popped off the stack on a return are local variables so you should be safe with the above code. However it is not good practice and I don't recommend it because C provides a much better system for doing this.
Just food for thought.
Last edited by VirtualAce; 08-01-2003 at 07:22 AM.
Hey Bubba,
Thanks for repeatedly demonstrating your knowledge of assembly language in your recent posts, however this is a C++ forum, so you can stop posting answers discussing assembly language--it is not at all helpful. In the future, try to speak to your audience, which in this case is someone who has clearly stated that they don't understand pointers and references.
Last edited by 7stud; 08-01-2003 at 10:41 AM.
Since C++ allows inline assembly, I think his post is valid.
actually if you looked at bubba's code...
2/3 of it was C++
and he makes a VALID and GREAT point, directly answering the question. I don't see what the problem is.
I enjoy looking at his ASM.
Now, as an answer to the question.
Very VERY easily.
and a quick question for bubba:Code:struct ret_mult { int first; int second; }; ret_mult returner(int a,int b,int c,int d) { ret_mult ret = {a+b,c+d}; return ret; }
I thought the parameters were in eax...
like
-LCCode:movl $0x1, %eax call do_something
Asking the right question is sometimes more important than knowing the answer.
Please read the FAQ
C Reference Card (A MUST!)
Pointers and Memory
The Essentials
CString lib
arrays are always passed by reference. & or notOriginally posted by hsv
For this to work you'd still need to pass by ref.
Code:void func(double &number[])
An array is just a non-dynamically allocated pointer to a section of memory.
char a[10];
char * p = new char [10];
a[0] = 'A';
p[0] = 'P';
See? All the same thing. Therefor the memory pointer to can be altered by the value of the pointer itself could not be. Personally, I'd pass by reference to avoid confusion and to make the intent clear anyhow.
>>so you can stop posting answers discussing assembly language--it is not at all helpful.
Yes. It is... And stop being obnoxious.
Why would you need a function to return multiple values anyhow? More than likely what you need is to pass in a few variables by reference and have your function adjust them.
"There's always another way"
-lightatdawn (lightatdawn.cprogramming.com)
Parameters in EAX?Code:int ReturnFoo(int a,int b,int c,int d) { _BX=c+d; return (a+b); }
Lynux - the parameters to any function lie at positive offsets to EBP. This is because before the function is called, the parameters are pushed onto the stack and the stack pointer is altered. Any local variables will lie at negative offsets to EBP - thanks a million to Compuboy from flashdaddee for reminding me of this. All explicit return registers are basically undefined on entry into a function EXCEPT when said function expects certain values in EAX,EBX,ECX,EDX, etc. But those functions that do not use those registers are free to place any values in them they want. Try it and see. Enter a function w/o placing values in the explicit return registers and then inside of the function, print the register values. You will see that they contain the last value placed in them which means the function call did not touch them.
Most DOS functions used AX (more like AH and AL) to represent function numbers or sub-function numbers for their OS functions. If you look at the RBIL - you will see that a lot of diff companies and programmers use the registers for a multitude of different things. There wasn't really a standard across all PCs AFAIK.
Your AT&T syntax is killing me, but I'll forgive you just this once.
Multiple values in one return statement
I've always wondered why C allows you to return multiple values in one return statement - where the heck is the other value stored?? I have no idea. In your code Lynux (C code that is), I'm not sure what EAX would hold. I experimented with this before and I think that the compiler only returns the first value and ignores the rest of the line, but I could be wrong.
Thanks
And to everyone who did....thanks for supporting me. I was only trying to help.
Be nice 7stud
Perhaps I did get a bit carried away 7stud, but my post did not warrant your lack of respect for a fellow board member.
Also I made a somewhat incorrect statement. Upon returning local variables are not popped off of the stack, parameters are. Local variables are dealt with by placing the base pointer (bp) into the stack pointer (sp). In this way the local variables will effectively disappear from the stack as other code writes over them on the stack. Popping local variables off of the stack would most certainly cause a crash UNLESS they were actually pushed onto it by a push instruction.
Sorry for the mixup.Code:push bp mov bp,sp sub sp,10 ... ... mov sp,bp ;restores the stack pointer to the base pointer ;effectively 'erasing' our local stack space ;popping anything else here would cause a crash - nothing else ;has been pushed onto the stack. pop bp
Last edited by VirtualAce; 08-02-2003 at 05:43 PM.