Redefining global variables in a function

I have a global variable, f, that determines the direction to drive in (-1 is backwards, 1 is forward). For my automatic movement via odometry, this variable is automatically set in a separate function. However, I want it to also be able to manually set, so I made a function that is essentially:
void DF (int f, int degrees) { drive all motors f*degrees; }

If when calling the function, I wrote
DF (f, 100);
would it simply use the previous used f value?

Thank you

Would this help?

As a side note, why not just use a boolean?

3 Likes

you can pass a global to functions as long as its not being covered up by something in the local namespace, class, or function. However, to avoid confusion, you should try to use different names for variables in different scopes

3 Likes

Because if he uses -1 and 1 for f rather than a boolean, he can set the direction by multiplying the power he wants to apply to the motor by f which is faster and more space efficient than using a conditional.

1 Like

what about (f?1:-1)

Fair.

You don’t need to do that though

but you could though

You could also use an if/else statement, but again,

1 Like

I feel as though I did not clarify what my question is well.

I am asking specifically about whether having a function with int f in the parameters would have any issues with defining f as f inside the function.

Essentially does:

void DF (int f, int g) {
move;
}

DF (f, 100);

have any issues with f being set to f?

There’s a balance in writing code between making it understandable and making it “fast”. Modern compilers generally apply a number of methods to optimize code. I will guarantee that one would not be able to discern the difference in execution between:

void DF(int f, int degrees) {
  LM.spin( f * degrees);
  RM.spin( f * degrees);
}

And:

void DF(bool fwd, int degrees) {
  if(fwd) {
    LM.spin( degrees);
    RM.spin( degrees);
  } else {
    LM.spin( -1 * degrees);
    RM.spin( -1 * degrees);
  }
}

In this case -1 and 1 for reverse and forward make sense. In other cases (maybe “left” versus “right”), it may be confusing to keep track of which value is which. One can use #define (which is technically a preprocessor (from the compiler’s point-of-view)) to alias values to make code more readable.

For example:

#define FORWARD 1
#define BACKWARD -1
// ... code and some declarations

DF(FORWARD, 360);
DF(BACKWARD, 360);

Is much easier to understand than:

// ... code and some declarations

DF(1, 360);
DF(-1, 360);

These directives can lead to other readability issues, consider:

#define FORWARD 1
#define BACKWARD -1
#define LEFT 1
#define RIGHT -1
// ... 

DF(LEFT, 360);
DF(RIGHT, 360);

Will do the same as the first example, but it is not obvious to a human that this is the case.

One can use enum to do the same, with the benefit that the compiler will catch “mistakes” like the above (syntax may be off):

enum fwd_rev {fwd=1, rev=-1};
enum left_right {left=1, right=-1};

void DF(fwd_rev dir, int degrees) {
  LM.spin( static_cast<int>(dir) * degrees);
  RM.spin( static_cast<int>(dir) * degrees);
}

// ... 

DF(fwd_rev::fwd, 360);
DF(fwd_rev::rev, 360);
DF(fwd_rev::right, 360);   // Compiler error
DF(left_right::right, 360);   // Compiler error
5 Likes

The way C++ handles scoping, this will “work”. However, you are setting yourself up for a potential landmine. Suppose you start out with:

int f = 1;

void DF (int f, int g) {
  move(f,g);
}

DF (f, 100);
DF (-1, 100);

This compiles, you run it, life is good. Then, you come back and decide to change it to be more “readable” and do:

int f = 1;
void DF (int forward, int degrees) {
  move(f,degrees);
}

DF (f, 100);
DF(-1, 100);  // Why won't this go backwards!?!?!?!?!?!?!?!?

You’ve made a small mistake. The compiler would have caught this mistake had you not had a global variable named the same as your function’s parameter.

It may be the case that the compiler will give you a warning with the way you have it currently written.

4 Likes