I know there are a couple of threads dealing with how to return more the one result from a function - and there are probably hundreds of ways to do it. How ever - I'm interested to know if - and how this will work:
int Test(){
int a = 2;
int b = 4;
return a, b;
}
I know this will NOT work in standard c++. How ever with the Arduino IDE it complies without errors - so I assume it's valid.
The question is: How can I access the value a and b from the calling function - or is this a compiler error?
return a,b; is the same as return b; Meet the comma operator - one of a number of syntactically valid constructions in c that has little to no legitimate use case, acting as traps for the unwary. Comma operator - Wikipedia
If your function needs to get two or more values to the calling environment, either:
use globals
return a struct
pass pointers to the function, and let it assign the output values to those
pack the two values into a single larger datatype, and unpack them on the other side.
Delta_G:
There may be hundreds of ways to get that data but there are exactly 0 ways to return two values. A function can only return one value. That one value may be a strictstruct full of values, but from the functions point of view he only returns one thing.
elisedd:
I know this will NOT work in standard c++. How ever with the Arduino IDE it complies without errors - so I assume it's valid.
The question is: How can I access the value a and b from the calling function - or is this a compiler error?
Delta_G:
There may be hundreds of ways to get that data but there are exactly 0 ways to return two values. A function can only return one value. That one value may be a strict full of values, but from the functions point of view he only returns one thing.
You wanted to fool the Compiler using return a, b; thinking that it will make a way to return two values (a, b). The Compiler is made to remain careful to comply with the syntax/semantics rules of the C/C++ Language and accordingly it ignores the first argument (a) during compilation process. Consequently, it will return only one value -- the value of b (4).
void setup()
{
Serial.begin(9600);
int x = Test();
Serial.print(x, HEX); //prints 4
}
void loop()
{
}
int Test()
{
int a = 2;
int b = 4;
return a, b; //return a, b; ----> return b;
}
GolamMostafa:
The Compiler is made to remain careful to comply with the syntax/semantics rules of the C/C++ Language and accordingly it ignores the first argument (a) during compilation process.
The first expression is EVALUATED at RUN TIME. Its result is then discarded.
AWOL:
NO.
It evaluates the first expression and ignores the result.
Edit: Curses! Beaten to the bell.
The following codes evaluates a = b*4 and applies this value to evaluate b = a+3 and then returns the value of b (19). How to explain it? All are cursed who do not make reasonable guess and misguide the audience?
void setup()
{
Serial.begin(9600);
int x = Test();// put your setup code here, to run once:
Serial.print(x, DEC); //prints 19
}
void loop()
{
}
int Test()
{
int a = 2;
int b = 4;
return a = b*4, b=a+3; //a = 16; b = 19
}
GolamMostafa:
The following codes evaluates a = b*4 and applies this value to evaluate b = a+3 and then returns the value of b (19). How to explain it? All are cursed who do not make reasonable guess and misguide the audience?
void setup()
{
Serial.begin(9600);
int x = Test();// put your setup code here, to run once:
Serial.print(x, DEC); //prints 19
}
void loop()
{
}
int Test()
{
int a = 2;
int b = 4;
return a = b*4, b=a+3; //a = 16; b = 19
}
What are you smoking, dude?
What don't you understand about "evaluates the first expression"?
OP: As you have seen, a C function cannot return more than one value. If you need the function to change two values, use pointers or put the values in a struct and pass the struct to the function. Here's a simple way using an array:
void setup() {
int a, b;
int array[2];
a = 5;
b = 10;
array[0] = a;
array[1] = b;
Serial.begin(9600);
while (!Serial);
test(array);
for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++) {
Serial.print("array[");
Serial.print(i);
Serial.print("] = ");
Serial.println(array[i]);
}
}
void test(int *a)
{
a[0] *= a[0];
a[1] *= a[1];
}
void loop() {
}
There is another way. Create your own stack, which is not unlike global variables, but perhaps a bit more general. You can push as many values on to it as you need from within the the function and then pop them outside. One stack, say 32 bytes, can be used for you entire program.
I know there are a couple of threads dealing with how to return more the one result from a function - and there are probably hundreds of ways to do it. How ever - I'm interested to know if - and how this will work:
int Test(){
int a = 2;
int b = 4;
return a, b;
}
I know this will NOT work in standard c++. How ever with the Arduino IDE it complies without errors - so I assume it's valid.
The question is: How can I access the value a and b from the calling function - or is this a compiler error?
THX Ellis
To pack:
long abPacked = (((long)a) << 16) + (((long)b) & 0xFFFF);
To unpack:
int a = ((abPacked >> 16);
int b = (abPacked & 0x7FFF);
if (abPacked & 0x8000L) {
b -= 0x4000;
b -= 0x4000;
}
It just seems to me that the most efficient way is to have the "return variables" packed into a 'struct' that's local to the calling function. Then, call the function that will do the processing and pass it a pointer to that 'struct'. This function does its job, computes values, and fills in the 'struct' using the passed pointer. Then, return 'void'.
This method minimizes the stack pushing and popping. It's got to be better than pushing the whole friggin 'struct' on to the stack just pop it off again.
econjack:
OP: As you have seen, a C function cannot return more than one value. If you need the function to change two values, use pointers or put the values in a struct and pass the struct to the function. Here's a simple way using an array:
Or forget the array, and use references
void setup() {
int a = 5;
int b = 10;
Serial.begin(9600);
while (!Serial);
test(a, b);
Serial.print("a = ");
Serial.print(a);
Serial.print(", b = ");
Serial.println(b);
}
void test(int& a, int& b)
{
a *= a; // just watch out for overflow!
b *= b; // ditto
}
void loop() {}
The three suggestions of an array, pointers, or references are really all the same thing: pointers. Given the rules for returning values from a function, it's about the only option for permanently changing multiple values on a single call.