Efficiency of a cast vs a shift
I tried compiling your three snippets with avr-gcc 4.9.2 at the -Os
optimization level (standard with Arduino) but without -flto. The
results were:


The first snippet generated inefficient code: the ands and shifts were
translated in assembly quite literally, the shifts were done on
16&nbsp;bits even though chan was declared uint8_t, and the last
shift was even implemented as a loop roughly equivalent to
uint16_t tmp1 = chan &amp; 15; uint8_t tmp2 = 3; while (--tmp2) tmp1 &lt;&lt;= 1;
The second and third snippets were translated identically and
efficiently, using the bst (bit store) and bld (bit load)
instructions to copy the relevant bit of chan into the second
argument of the digitalWrite() call.


Personally I would just write

digitalWrite(_S0, chan &amp; 1);    
digitalWrite(_S1, chan &amp; 2); 
digitalWrite(_S2, chan &amp; 4); 
digitalWrite(_S3, chan &amp; 8);


as digitalWrite() expects an integer as its second argument, and it
interprets it just like the (bool) cast does. If you want to be sure
to always call digitalWrite() with either 0 (LOW) or 1 (HIGH),
then use either your second of third form. The first form seems formally
equivalent to the second, but since it is not an usual C idiom, the
compiler could not catch the optimization opportunity.