Functions and return a, b;

Hi,

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

(deleted)

THX for the fast answer Faraday - you mentioned one of the 1000 ways - but unfortunately this was not the question...

The question was: Will it work in the given way - and when how - or is it a "false true" - and a compiler error...

THX Ellis

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.

THX DrAzzy :slight_smile: got it. Wiki helps indeed :-)...

Or use references.

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.

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

NO.
It evaluates the first expression and ignores the result.

Edit: Curses! Beaten to the bell.

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"?

AWOL:
What are you smoking, dude?

My guess would be discarded outdated technical documents, not used as cigarette paper, but pure.

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.

elisedd:
Hi,

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.

struct myStruct {
  float var1;
  uint8_t var2;
  uint32_t var3;
  char charBuffer[20];
};

void workingFunction(myStruct *);

void setup() {
  myStruct myStructInstance;
  workingFunction(&myStructInstance);
}

void loop() {}

void workingFunction(myStruct *dog) {
  dog->var1 = 3.14159;
  dog->var2 = 42;
  dog->var3 = 7743;
  strcpy(dog->charBuffer, "Hello World");
}

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() {}

TolpuddleSartre:
Or forget the array, and use references

I don't see any advantage to this over just passing in a couple of pointers.

I wouldn't be surprised if the generated object code was identical.

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.