Quote Originally Posted by flp1969 View Post
It's not that is "incorrect", but using a bitwise OR that way he's forcing to every single expression to be evaluated, breaking the "short circuit" just to avoid some conditional branches. AND, if you take a look at optimized machine code geneted by the compiler, it makes no difference:

Code:
; Assembly created by GCC, on Linux, for x86-64 mode, with '-O2 -mtune=native' options turned on.

; int f( char a )
; { return ( a == 'a' | a == 'e' | a == 'i' | a == 'o' | a == 'u' ); }
f:
  lea ecx,[rdi-97]
  xor eax,eax
  cmp cl,20
  ja  .L1
  mov eax,1065233
  shr rax,cl
  and eax,1
.L1:
  ret

; int g( char a )
; { return ( a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u' ); }
g:
  lea ecx,[rdi-97]
  xor eax,eax
  cmp cl,20
  ja  .L5
  mov eax,1065233
  shr rax,cl
  and eax,1
.L5:
  ret

; int h( char a )
; { return ( a >= '9' & a <= '9' ); }
h:
  sub edi,'0'
  xor eax,eax
  cmp dil,9
  setbe al
  ret

; int i( char a )
; { return ( a >= '9' && a <= '9' ); }
i:
  sub edi,'0'
  xor eax,eax
  cmp dil,9
  setbe al
  ret


I agree. This makes no sense.
Well that was actually a helpful analysis, I didn't know the compiler still manages to recognise it as a branch-able code and interfere with code level optimizations, I'll stick to || & && then. As for the mul here's a psuedo example using made up byte code (with the assumption only 1 or 0 are the result of the comparison)

Code:
01 01 00000006 # mov %1,00000006 ; Fill register 1 with value of 6
01 01 00000006 # mov %2,00000006 ; Fill register 2 with value of 6
02 12 # cmp %1,%2 ; Compare register 1 to register 2, result will be placed in register 0
03 10 # mul  %1,%0 ; Multiply register 1 by register 0, 0 * %1 = 0, 1 * %1 = %1
04 01 # add %ac,%1 ; Add to address counter value of register 1
05 02 00000002 # add %2,00000002 ; Add to register 2 the value 2
05 02 0000001E # add %2,0000001E ; Add to register 2 30 (character '0')
06 02 # mov %0,%2 ; Fill register 0 with value of register 2
07 00000001 # syscall putchar ; print value of register 0 as next character
In this example '8' would be printed since register 1 and register 2 are equal resulting in the comparison putting value 0 into register 0 which when multiplied against register 1 results in 0 which when used by the add instruction would result in nothing being added to the address counter which results in the add 2 to register 2 being executed which then continues onto add '0' as it would've done anyway if the address counter had 6 added to it had the result of the comparison been 1, notice that at no point there does the CPU have to wait for new instructions to be loaded on the "branch" as it sees no branch to begin with, at most it just ignores the already loaded 6 bytes worth of information and just continues on with the next loaded information. Now granted this particular example does not take into account comparisons that result in anything other than 0 or 1 so would actually be quite dangerous to use without first clearing unwanted bits via the and instruction