why -1 evaluates true
Languages that do not have native boolean data-types that let you branch on non-boolean data types evaluate all non zero values as “truthy”, (-1) evaluates to true. You might be wondering, as I did, why that is? After poking around and looking at some x86 assembly instructions, I suspect it is a compiler optimization.
At first I thought it was a perl specific choice, but a few quick tests with C and Python confirmed this was not the case.
It seemed like an odd design choice given that truthiness in this (programming) context is quasi-inspired after the presence of current in a given transistor. So why wouldn’t you want negative integers to be false?
Then I started thinking that it was either an optimization issue — so I started looking at the x86 assembly generated by GCC for my C example (see below). I used the -S flag to gcc to save the assembly so gcc -S test.c created the test.s (assembly). A quick glance revleaed that this was indeed the case, particularly the following three lines:
movl $-1, -4(%rbp) cmpl $0, -4(%rbp) je .L2
movl moves the value of X (-1) to the appropriate place (this is int x = -1) then the actual comparison happens with the cmpl operator which compares that value to zero. If those to values are equal (0 and X) the je executes (jump-if-equal) and executes that branch.
Now the next question, for another day, why is gcc assembly ifs to JE and JLE — which would return false for anything less than 1 for example.
My guess is because it’s more expensive. But more to come on that subject.
perl:
#!/usr/bin/env perl
if (-1) {
print STDERR "I am true \n";
}
python:
#!/usr/bin/env python num = -1 if (num): print "I am true"
C:
#include
int main (void) {
int x = -1;
if (x) {
printf("I am true");
} else {
printf("not true");
}
}
Filed under: Programming