Em seg., 3 de ago. de 2020 às 16:14, Sjoerd Mullender <sjoerd@monetdb.org> escreveu:


On 03/08/2020 18.29, Ranier Vilela wrote:
> Em seg., 3 de ago. de 2020 às 13:22, Sjoerd Mullender
> <sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>> escreveu:
>
>
>
>     On 03/08/2020 17.55, Ranier Vilela wrote:
>     > Em seg., 3 de ago. de 2020 às 12:50, Sjoerd Mullender
>     > <sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>
>     <mailto:sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>>> escreveu:
>     >
>     >
>     >
>     >     On 03/08/2020 15.43, Ranier Vilela wrote:
>     >     > Em seg., 3 de ago. de 2020 às 04:02, Sjoerd Mullender
>     >     > <sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>
>     <mailto:sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>>
>     >     <mailto:sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>
>     <mailto:sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>>>> escreveu:
>     >     >
>     >     >     Either way is correct.
>     >     >
>     >     > Are we missing something?
>     >     >
>     >     >     The first form evaluates both (b->ttype != TYPE_void) and
>     >     b->tkey, both
>     >     >     of which result in either 0 or 1.  The single & does a
>     >     bit-wise AND on
>     >     >     those two values and results in 1 if both sides
>     evaluated to 1.
>     >     >
>     >     >     In the second form, if first part evaluates to 0,
>     b->tkey is not
>     >     >     evaluated,
>     >
>     > Sorry, see:
>     >  " In the second form, if first part evaluates to 0, b->tkey is not
>     > evaluated,"
>     > No matter the outcome of the first part, b-> key will always be
>     evaluated.
>     >
>     >     and if the first part evaluates to 1, the second part is also
>     >     >     evaluated.  The restult, again, is only 1 if both sides
>     >     evaluate to 1.
>     >     >
>     >     > Wait, bitwse AND (&) is not shortcut, If first part
>     evaluates to 0
>     >     > *b->key is stiil evaluated.*
>     >
>     >     That's correct.  I think I mentioned that.
>     >
>     > Sorry, but I think it contradicts your first email, you say "not
>     > evaluated".
>
>     I wrote (and I copy/paste):
>     "The first form evaluates both (b->ttype != TYPE_void) and b->tkey"
>     and
>     "In the second form, if first part evaluates to 0, b->tkey is not
>     evaluated"
>
>     The first form being the one with the bitwise &, the second form being
>     the one with the logical &&.
>
>     In any case, with & both sides are always evaluated and there is no
>     shortcut.  With && if the left side evaluates to 0, the right side is
>     not evaluated.
>     The thing is, in order to skip evaluation, a jump is needed over the
>     code that does the evaluation.  Conditional jumps may be expensive.  So
>     it may be faster to evaluate both sides (and not jump) than to skip
>     evaluation of one side at the cost of a conditional jump.  (It's the
>     conditionality that makes it potentially expensive.)
>
> I agree with you about trick to gain performance.
>
> But this:
> if (b->ttype != TYPE_void) & b->tkey)
>
> Is the same write:
> if (b->key)
>
> And if is correct, was that the original intention?

No it is not the same.
Look at the four possibities.  Either (b->ttype != TYPE_void) is either
0 or 1, and b->tkey likewise is either 0 (false) or 1 (true).  The four
possibilities therefore are
0&0, 0&1, 1&0, 1&1.  The results are thus
0    0    0    1
In other words, only if the first part evaluates to 1 is the result
equal to the value of b->tkey, but if the first part evaluates to 0, the
result is 0, no matter the value of b->tkey.
int main()
{
  int r;
  r = (0 & 0);
  printf("r = (0 & 0) = %d\n", r);
 
  r = (0 & 1);
  printf("r = (0 & 1) = %d\n", r);

  r = (1 & 0);
  printf("r = (1 & 0) = %d\n", r);

  r = (1 & 1);
  printf("r = (1 & 1) = %d\n", r);
}
output:
r = (0 & 0) = 0
r = (0 & 1) = 0
r = (1 & 0) = 0
r = (1 & 1) = 1

(b->type != TYPE_void)       &    b->key = result
(b->type != TYPE_void)=0          =0     = 0
(b->type != TYPE_void)=0          =1     = 0
(b->type != TYPE_void)=1          =0     = 0
(b->type != TYPE_void)=1          =1     = 1

Yeah, complex, but finally I got.
Thanks for the explanations and sorry by the noise.

regards,
Ranier Vilela