Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is (x || !x) false?

A friend of mine jokingly asked me this question. It was meant to be a "goes without saying" type remark, but then I actually thought about it for a while and started coming up with some clever "almost solutions".

First attempt:

If C ever supports quantum computing there may be an answer to this. A q-bit can be in many states at once, so it could be false AND true and this conditional will return (BOOL)0.5 aka "Yes/no/maybe-so" - but once you observe the variable the whole thing will collapse and become invalid again.

Second attempt:

If X could somehow be defined as a random binary generator and you cast it to a BOOL you could get false some of the time. I'm not sure if you can do this though in C unless you use CLANG. #define x (BOOL)!!(rand()%2)



The language we were discussing this in is C but I'm also curious if anyone can find any solutions in any language.

like image 622
Albert Renshaw Avatar asked Feb 28 '16 21:02

Albert Renshaw


4 Answers

When x is volatile (volatile int x) and is modified by an external thread / device, the expression can be false.

like image 153
Amit Avatar answered Nov 01 '22 09:11

Amit


It's a bit of a trick, but the following solution also works:

#define x 1 ? 0 : 1
(x || !x)

The reason is in the operator precedence. After preprocessing (x || !x) resolves to the following (parentheses added to show the precedence):

(1 ? 0 : (1 || !1) ? 0 : 1)
like image 27
Dirk Herrmann Avatar answered Nov 01 '22 10:11

Dirk Herrmann


Macros are really cheating here, but you don't need anything to do with boolean types or special compilers. The following, as far as I know, is legal standard C.

#include <stdio.h>
int f(void) { 
  static int y = 0;
  if (y == 0) {
     y = 1;
     return 0;
  } else {
    return 1;
  }
} 

#define x f()

int main(void) {
  if (x || !x) {
    puts("It was true");
  } else {
    puts("It was false");
  }
  return 0;
}

Or even more concisely:

int y = 0;
#define x y++

(For those worried about undefined behavior, note there is a sequence point between the left and right side of ||.)

like image 5
Nate Eldredge Avatar answered Nov 01 '22 10:11

Nate Eldredge


An even simpler macro:

#define x 0&0

expanding (x || !x) gives (0 & 0 || !0 & 0) which is always false.

Similarly:

#define x 0*0
#define x 1*0  // for binary buffs
#define x 4&2  // for HHGG fans.

I could not find a 2 letter macro :(

like image 5
chqrlie Avatar answered Nov 01 '22 10:11

chqrlie