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