Define a constant for an expression

Here is a part of the code from one of my projects. The last value of 10 will change but the expression a != 0 && b != 0 && abs(a - b) <= will remain constant across multiple loops. How can I define a constant for this expression?

if (measureComplete) {
    if (a != 0 && b != 0 && abs(a - b) <= 10) {
        //code
    }

You mean, like, a function?

The problem is that the final expression has three booleans, and you want to make a "constant" out of 2-2/3 of them. You might be best off using a macro, and let the compiler sort it out

#define non_zero_diff_lte(a,b,x) ((a) && (b) && abs((a) - (b)) <= (x))

If it's always a and b

#define non_zero_diff_lte(x) (a && b && abs(a - b) <= (x))

In the former case, a and b could be anything, so each requires their own parentheses. In the latter, it's only required for the final value (and the whole thing).

if (measureComplete) {
    if (non_zero_diff_lte(10)) {
        //code
    }

You can of course call this macro whatever you want; maybe something shorter with a better name for that final value.

1 Like

macros that use there arguments multiple times are particularly dangerous, because they can cause what you THINK was a single "fetch" of a value to happen multiple times. In this case, a function will work fine, and is probably a good idea:

bool non_zero_diff_lte(long a, long b, long x) {
  return ((a) && (b) && abs((a) - (b)) <= (x));
}

(change types of a,b,x as appropriate.)

2 Likes

You can define this function as "constexpr". The comparison then takes place at compile time and is replaced by the result in the finished program. At runtime, the function is "already executed".

constexpr bool non_zero_diff_lte(long a, long b, long x) {
  return ((a) && (b) && abs((a) - (b)) <= (x));
}

Good point. Going further, one reason to make a constant is to eliminate all further evaluation. One could rely on the <= part with an arbitrarily high number

int diff_or_999 = a && b ? abs(a - b) : 999;

//...

if (measureComplete) {
    if (diff_or_999 <= 10) {
        //code
    }

(I would use std::numeric_limits<int>::max(), but you can't(?) on AVR....)

Only if the function's parameters are known at compile time. @electrophile's post was not clear on that point.

1 Like

Yes, thats true…