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");
  }
}
  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Reddit

blog comments powered by Disqus