

Why 1 && 2 == 2 - boyter
http://blog.chewxy.com/2013/07/19/why-1-2-2/

======
pbsd
In C++, << has higher precedence than &&, so in effect what is being done is

    
    
        (cout << 1) && 2;
    

...which is not an error, since the result of operator<< is an std::ostream,
which is convertible to bool. Therefore operator&&(bool, bool) is invoked but
the result is, of course, discarded.

Disambiguating the expression with parentheses should output 1 in every case.

~~~
chewxy
I wrote the article (didn't plan on HN traffic, thanks Boyter). I've fixed it
with your comment.

Thanks

------
binarycrusader
For Python, a common idiom is to do this:

condition and truecase or falsecase

See "Boolean operations" and "Conditional expressions":

[http://docs.python.org/3/reference/expressions.html#boolean-...](http://docs.python.org/3/reference/expressions.html#boolean-
operations)

~~~
jes5199
ah! I've been trying to write Python lately (I'm more of a Rubyist) and the
internet suggested:

truecase if condition else falsecase

which is so inside-out that it hurts.

It didn't occur to me to use the boolean style - I guess I think of that as a
perl idiom, and assumed that it would get sneered at in py-land

~~~
pyre
I've never seen:

    
    
      $CONDITION && $TRUE_CASE || $FALSE_CASE
    

used as a Perl idiom in lieu of:

    
    
      $CONDITION ? $TRUE_CASE : $FALSE_CASE
    

I can't claim to have worked with Perl much prior to Perl 5.6/5.8 though, so
it may have been an older idiom (though I doubt it as one of Perl's influences
was Awk, which also has a C ternary operator, IIRC).

That said, using truthy/falsey values in Python doesn't seem super common. I
surprised a couple of interviewers by doing that while implementing some tree
manipulation functions.

------
rayiner
How did he get an expression that shouldn't involve any memory references to
segfault?

~~~
chewxy
I suck at C?

~~~
cldr
He probably thought pointers are the only kind of variables and that he needed
to dereference them. I imagine something like

    
    
        int *a = 1, *b = 2;
        printf("%d\n", *a && *b);
    

Either that or he used `%s` as a format specifier. That seems more probable.

Edit: Or, as I just realised the people below me meant,

    
    
        printf(a && b);

~~~
chewxy
Nah mate, it's just some compiler flag that I didn't turn on (don't know
which. my gcc-fu is fail since it's been really a long time since I touched C)

~~~
cldr
Just for my curiosity's sake, would you mind posting the code you tried that
segfaulted?

~~~
georgemcbay
Yeah I'm dying to see the original C code but it isn't on the page anywhere,
AFAICT.

From the article, about the C version: "Mine hadn't worked, which I suspect is
some sort of compiler issue."

Yeah I'm going to go out on a limb and proclaim that there's no way this was
due to a compiler "issue" in gcc. Not that gcc is perfect, but there's no way
it is barfing on one of these handful of line programs that does nothing but
some logical operations and printfs.

~~~
chewxy
Nope. The answer is still I suck at C.

Parts of the blog post was written late last night (about 3 am), and parts of
it was written on my commute to work. I tried to rewrite what I wrote last
night and tried to compile it on my work computer, and all I got were
warnings.

So... can't recreate. Sorry

------
lotharbot
Once you understand short-circuit evaluation, it opens up certain coding
tricks.

The line "[operation] or [error condition]" will attempt the operation on the
left. If it succeeds, the program continues on the next line, ignoring the
part about the error condition. If it fails, the error condition will execute
instead. This might be something like "open file or die".

Likewise, "[operation] and [success condition]" will attempt the operation on
the left, and if it succeeds, perform the operation on the right. This might
be something like "read input and process it", which will perform the
(possibly expensive) processing step only when input is received.

Code written in this style is sometimes, but not always, faster to execute.
It's also sometimes, but not always, clearer.

See also [http://en.wikipedia.org/wiki/Short-
circuit_evaluation](http://en.wikipedia.org/wiki/Short-circuit_evaluation)

~~~
cldr
This is commonly seen in Perl and PHP with stuff like

    
    
        launchMissiles() or die('failure');

~~~
k3n
Ugh, `or` is mostly useless in PHP.

That code is identical to:

    
    
        launchMissiles() || die('failure');

~~~
ars
That code is the same, but or has a lower priority than ||, so they are not
the same is the code before the or is an expression.

Also, using or instead or || for these types of things is more readable since
it makes your intent of conditional code execution (as opposed to boolean
evaluation) clear.

~~~
k3n
Meh, it's not more unreadable unless you have issues understanding || in the
first place... and "or" is still a boolean operation.

Considering 99.9% of it's use in PHP is some variant of "connect() or die()",
I stand by my statement. Besides, those "connect() or die()" expressions are
widely considered bad-practice in the first place.

------
eridius
You wrote at the end that you weren't sure why literal values were returned
instead of TRUE and FALSE. The practical answer is that literal values are far
more useful. The simple answer is that, since the literal value already
represents TRUE (or FALSE), returning it makes just as much sense as returning
a literal TRUE/FALSE, and is simpler to do.

------
adamnemecek
Just FYI, you are doing something wrong if your C code segfaults.

EDIT: Oh, missed the errata.

------
betterunix
Common Lisp treats any non-nil value as "true," so the behavior is not _bad_
for the "and" macro (yes, it is a macro). Additionally, the standard says that
"and" should evaluate to nil if any argument evaluates to nil, or to its last
argument otherwise:

[http://www.lispworks.com/documentation/HyperSpec/Body/m_and....](http://www.lispworks.com/documentation/HyperSpec/Body/m_and.htm)

------
codyb
Worth it for the memoization (I guess that's not really a word?) in Ruby. Cool
new operator I did not know about.

~~~
city41
It's not a new operator, but rather the X= form, where `foo X= 4` is sugar for
`foo = foo X 4`

Just be careful with this in JavaScript, as the greater number of things that
are falsy can bite you if you do `a = a || 10;`, which is a very common JS
bug.

------
jcampbell1
Thank god he didn't try php.

    
    
        echo 2 && 1; // 1
        echo 1 && 2; // 1
        echo 2 || 1; // 1
        echo 1 || 2; // 1
        echo 2 ?: 1; // 2
    

In php ?: is javascript's || Unfortunately there is no && that works
correctly.

~~~
mattparlane
Came here to say this. If you use var_dump you can see it's coercing the
result to a bool.

    
    
        $ php -r 'var_dump(1 && 2);'
        bool(true)

~~~
RossM
Exactly, it's not _that_ bizarre. PHP assumes when you're using && you're
going to have a boolean outcome.

The odd bit is that casting a boolean to a string[0] with echo coerces the
result to (string) "1" for true and (string) "" for false.

[0]:
[http://www.php.net/manual/en/language.types.string.php#langu...](http://www.php.net/manual/en/language.types.string.php#language.types.string.casting)

------
unlimitedbacon
I am not a programmer, but it seems to me the logical thing to do would be to
operate on the binary values of 1 and 2.

Since 1d = 01b and 2d = 10b...

1 AND 2 = 01 AND 10 = 00 = 0

1 OR 2 = 01 OR 10 = 11 = 3

~~~
chewxy
That's kinda what binary logical operations are for. Typically AND is denoted
by the symbol '&', and OR is denoted by the symbol '|'

------
CamperBob2
I like how

    
    
      cout << 2 && 1 
    

demonstrates the lameness of the whole C++ iostreams syntax. I'll have to
remember that the next time an argument arises.

~~~
cldr
Feel free to change it to how you like it if you feel that another syntax
would be more convenient. You can choose another operator or just create a
variadic template function and use function syntax to avoid operator
precedence issues.

~~~
CamperBob2

      printf("%d", 2 && 1);
    

seems to work OK.

------
ctide
I think it's a sign that I've been programming (predominantly in ruby) too
long when I didn't think twice about why 1 && 2 == 2.

------
psuter
I sometimes wish that x * y would short circuit on x = 0. Just because you
could.

~~~
valleyer
You mean, like, in the compiler? If x is actually a macro that expands to
zero, that will (or at least should, for a sufficiently smart compiler)
happen. Otherwise, I can’t imagine a runtime check of this being appreciably
faster than hardware multiply. Right?

~~~
lubomir
I would guess he/she meant something along the lines of x *
some_really_complicated_expression. If x is 0, you would not need to evaluate
the other operand at all. It may even be a faster, but I doubt any compiler
does this sort of optimization, since it is not safe in languages with non-
pure functions. The complicated expression could change some global state or
perform input/output.

E.g. in Haskell, it would be possible to do this safely, because it is
guaranteed by the type system that there are no side effects. However, even
with literal 0 in the code the other operand still gets evaluated.

~~~
valleyer
Ah OK. That makes sense.

