Pages: [1]   Go Down
Author Topic: Problem passing function argument as reference  (Read 915 times)
0 Members and 1 Guest are viewing this topic.
Czech Republic
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi!
I think, that Arduino should support this normally, since it is the C++ standard, so I am probably just missing some stupid mistake...
But I'm pretty stuck on this. So - I have this neat function, that just reads some data from the mouse, I am interfacing and saves them into the arguments sent to it. Or it should do so... The problem is not the reading (Serial.print() inside this function gives me the correct data without problems), but the process of copying the values into the arguments (Serial.print() after the function gives me zero).

Here is a simplified code:

Code:
void get_mouse_data(int& mstat, int& left_encoder, int& right_encoder)

void setup(){}

void loop()
{
 int mstat = 0;
 int l_enc = 0;
 int r_enc = 0;
 
 get_mouse_data(mstat, l_enc, r_enc);

 Serial.print("LENC: ");
 Serial.print(l_enc);
 Serial.print(",RENC: ");
 Serial.println(r_enc);
  //this gives me zeros (rarely something, that doesn't make sense...) :(
}

void get_mouse_data(int& mstat, int& left_encoder, int& right_encoder)
{
 int data[2] = {0};
 mouse->report(data);
 mstat = data[0];
 right_encoder = -data[1];
 left_encoder = -data[2];

 Serial.print("LENC: ");
 Serial.print(left_encoder);
 Serial.print(",RENC: ");
 Serial.println(right_encoder);
  //this gives me correct data
}

I did even try it with pointers... Didn't help. What am I missing here?
Thanks for any tips!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 551
Posts: 46224
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gives you what problems?

Code:
int data[2] = {0};
 mouse->report(data);
 mstat = data[0];
 right_encoder = -data[1];
 left_encoder = -data[2];
You are declaring a local array with 2 elements, and initializing one of them. The other contains random garbage.

Then, you call a function that might, or might not, overwrite those 2 values.

Finally, you assign the 2nd and 3rd (of 2) of them to variables.
Logged

Czech Republic
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well... Actually the command
Code:
int data[2] = {0};
initializes the whole array, not just the first element.

But as you correctly pointed out, it creates an array of two elements, which is the problem...
Thanks for your fast answer, I didn't see this one by myself!
Logged

France
Offline Offline
God Member
*****
Karma: 29
Posts: 898
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone tell me why the sscanf function (for example) require that we pass referenced parameters with a '&' in front of them, like:
Code:
sscanf( str, "%d", val); // doesn't work

sscanf( str, "%d", &val); // work
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone tell me why the sscanf function (for example) require that we pass referenced parameters with a '&' in front of them, like:
Code:
sscanf( str, "%d", val); // doesn't work

sscanf( str, "%d", &val); // work

Because the sscanf function parses data from the provided string and stores it in val. If you don't pass a reference to the variable val, then sscanf has no way of changing the contents of val.
Logged

France
Offline Offline
God Member
*****
Karma: 29
Posts: 898
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I know but other functions using referenced parameters doesn't need the '&' in front of parameters..like this:
Code:
void func( int &val )
{
  val = 1;
}
...
int val;
func( val );
// val is now = 1
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I know but other functions using referenced parameters doesn't need the '&' in front of parameters..like this:
Code:
void func( int &val )
{
  val = 1;
}
...
int val;
func( val );
// val is now = 1

I'm not an expert but I'd say the compiler is smart enough to understand that an '&' in front of the variable in the function declaration means we want the address of whatever is passed to it. I'm used to the convention of function prototypes looking like this:

Code:
void func(int *val);

which is probably what sscanf uses.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There are function declarations and function invocation:

Code:
//function declaration
void func( int *val )
{
  val = 1;
}
...
int val;
//function invocation
func( &val );
// val is now = 1

The other way around, you are simply changing the value of a copy of "val" on the stack, which is lost once you exit the function.

Logged

UK
Offline Offline
Shannon Member
****
Karma: 184
Posts: 11197
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone tell me why the sscanf function (for example) require that we pass referenced parameters with a '&' in front of them, like:

Code:
sscanf( str, "%d", val); // doesn't work

sscanf( str, "%d", &val); // work

That is not using a reference, it is using a pointer.

The difference is in the way the variable is declared, not how the value is provided. Just to confuse the situation slightly, sscanf is an awkward example to use because it uses varargs; the declaration (function prototype) for sscanf() does not define the type of the third and subsequent arguments and instead they are implied by the content of the format string.

Logged

I only provide help via the forum - please do not contact me for private consultancy.

Czech Republic
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To Guix:

This might help you: http://www.cplusplus.com/doc/tutorial/pointers/
Logged

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can someone tell me why the sscanf function (for example) require that we pass referenced parameters with a '&' in front of them, like:
Code:
sscanf( str, "%d", val); // doesn't work

sscanf( str, "%d", &val); // work

References didn't exist in C so they had to use pointers.

I think it'd bad form to have your function accept a non-const reference because most things are passed by value so the caller doesn't have to worry about it getting modified and then can't tell when it might be. Adding the & character makes it much clearer that it will be modified.

Passing by const reference is fine so that huge objects don't need to be copied if they won't be changed anyway.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 184
Posts: 11197
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

References are just a bit of syntactic sugar round pointers, aren't they? I mean, the semantics of passing a value by a reference type are identical to passing it via a pointer, it just avoids the pointer syntax.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I know but other functions using referenced parameters doesn't need the '&' in front of parameters..like this:

sscanf is a C function. References were introduced in C++.

Quote
References are just a bit of syntactic sugar round pointers, aren't they?

To a certain extent, although since you can't change the "underlying" pointer the compiler lets you use references where it wouldn't let you use pointers (eg. for things that are const).
Logged

France
Offline Offline
God Member
*****
Karma: 29
Posts: 898
Scientia potentia est.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see, thanks now I understand smiley
Logged

Pages: [1]   Go Up
Jump to: