Compare a value to two other values in a single expression while referring to the first value only once

StackOverflow https://stackoverflow.com/questions/22108964

Question

Say you have a function, foo(), that returns a number.

You want to check if the return value is equal to N or M.

You could do foo() == N || foo() == M. But that requires calling foo() twice.

How would you make a single boolean C expression that does this while calling foo() only once?

Edit: As already stated in the title, I want to refer to the first value only once. And this must be in a single C expression, i.e., no temporary variables, which requires a separate declaration statement. Otherwise the answer is trivial.

Was it helpful?

Solution 2

You need a temporary to store the return value of foo in order to not call it twice, then you can do this in a straightforward way with a couple == and an ||. But if you really want the if as something more "atomic" you can do this with a temporary value like this:

  int temp;
  if (temp = foo(), !((temp ^ N) * (temp ^ M))) {
    // your code here
  }

It might save a branch from the short-circuit evaluation, depending on what the compiler generates.

Without a temporary:
If you don't care about modifying N and M, you can do the test in a statement without a temp. N' holds N ^ M, M' holds M ^ foo(). So N' ^ M' gives N ^ foo(). The comma operator is evaluated left to right and the expression is has a value equal to its hand side.

  if (N ^= M, M ^= foo(), !(M * (N ^ M))) {
    // your code here
  }

OTHER TIPS

if((x = foo()) == N || x == M) ...

Try

int x = foo();
if (x == N || x == M) ...

Seems rather obvious

Why not set the result of foo() to an intermediate variable?

x = foo();
if(x == N || x == M)
  ...

Suppose that N > M, N - M is a power of 2, and that our unsigned integers here are 32 bits.

There should be another power of 2, K such that k * (N - M) wraps around to 0.

If N - M is 2i, then K would be 232-i.

Then the expression !(K * (foo() - M)) will give the answer.

But this relies on many conditions; I'm looking for a solution for all possible N and M.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top