Monday, October 29, 2012

One of the few cases where I'll use the ternary operator.

The ternary operator in C/C++ is of the form "? : " and is mainly used to cram an if-statement into one line and write unreadable code :)

I generally steer clear of it but there is one type of situation where I'm willing to use it. Printing out the state of a boolean in a printf statement. C didn't have a boolean type, printf is from C, so there's no support in printf for boolean types. But booleans are an everyday type now and you'll often find yourself wanting to print out the state of a bool.

You can't do this:

printf("isSoundOn = %b", isSoundOn);

There's no escape character for bools but you can use the ternary operator.

printf("isSoundOn = %s", isSoundOn? "true" : "false");

That will do the trick. I think it's reasonably straight forward and actually doing a full if statement across multiple lines would make things harder to read for such a simple action. I did see an interesting alternative on Stackoverflow with no branch, from memory it was this:

&"false\0true"+6*isSoundOn

That probably needs some braces and maybe some casts to compile but basically it's moving the pointer to the start of the "true" substring if isSoundOn is true. If isSoundOn is true it will have a value of 1 otherwise 0, 6 is the length of false including the termination character. So 6 * 1 moves the pointer to "true", 6 * 0 keeps the pointer at the start of the string and printing will end when it reaches the terminating character \0. Clever but too magical for regular code I think.

Monday, October 22, 2012

GCC's new Local Register Allocator

Some messy code was cleared up the new GCC (GNU's C compiler) and apparently is used to be refered to as Satan. I thought that sounded a worth a skim. It's here for the interested: reload.c

I was about 1/3 of the way down, thinking - this isn't too bad, I've seen worse - then I reached this beauty of an if statement.

  if (out != 0 && GET_CODE (out) == SUBREG
      && (subreg_lowpart_p (out) || strict_low)
#ifdef CANNOT_CHANGE_MODE_CLASS
      && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass)
#endif
      && contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (out))]
      && (CONSTANT_P (SUBREG_REG (out))
   || strict_low
   || (((REG_P (SUBREG_REG (out))
  && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
        || MEM_P (SUBREG_REG (out)))
       && ((GET_MODE_PRECISION (outmode)
     > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
#ifdef WORD_REGISTER_OPERATIONS
    || ((GET_MODE_PRECISION (outmode)
         < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
        && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
     ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
      / UNITS_PER_WORD)))
#endif
    ))
   || (REG_P (SUBREG_REG (out))
       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
       /* The case of a word mode subreg
   is handled differently in the following statement.  */
       && ! (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
          > UNITS_PER_WORD))
       && ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode))
   || (secondary_reload_class (0, rclass, outmode, out) != NO_REGS
       && (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)),
       SUBREG_REG (out))
    == NO_REGS))
#ifdef CANNOT_CHANGE_MODE_CLASS
   || (REG_P (SUBREG_REG (out))
       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
       && REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
        GET_MODE (SUBREG_REG (out)),
        outmode))
#endif
   ))
    {
#ifdef LIMIT_RELOAD_CLASS
      out_subreg_loc = outloc;
#endif

I've never even seen if-defs in a if statement before! Mind-boggling - seems like the clause itself should be it's own small domain language. I've not even tried to pick it apart, and as usual blogger has messed up some characters escaping them but I'm sure the insanity shines through!

Thursday, October 04, 2012

September Review

This month, among many others things, I ported my small engine over to Android. Android development went much smoother when I totally ignored Eclipse and did everything from the commandline under cygwin. The development experience compared to Windows (or Console dev generally) isn't very friendly but I'm able to run the same program on my desktop and phone which is cool. I don't really have to touch the Android internals again, unless I want device specific features, such as camera access or something. I've not submitted the working build to any public source control but I have updated my github with android ports of all versions I've committed so far.