
Hi, At gdk\gdk_bat.c (line 1384) variable b->type is bool Would be a typo? if (((b->ttype != TYPE_void) & b->tkey) && b->batCount > 1) { Should be: if (((b->ttype != TYPE_void) && b->tkey) && b->batCount > 1) { regards, Ranier Vilela

Either way is correct. 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, 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. So the difference is whether or not b->tkey is evaluated, and evaluating that is cheap (it's a bool value). On 01/08/2020 20.54, Ranier Vilela wrote:
Hi,
At gdk\gdk_bat.c (line 1384) variable b->type is bool
Would be a typo? if (((b->ttype != TYPE_void) & b->tkey) && b->batCount > 1) { Should be: if (((b->ttype != TYPE_void) && b->tkey) && b->batCount > 1) {
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list
-- Sjoerd Mullender

Em seg., 3 de ago. de 2020 às 04:02, Sjoerd Mullender <sjoerd@monetdb.org> escreveu:
Either way is correct. 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, 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.
So the difference is whether or not b->tkey is evaluated, and evaluating that is cheap (it's a bool value).
Thanks for the explanation. regards, Ranier Vilela

Em seg., 3 de ago. de 2020 às 04:02, Sjoerd Mullender <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, 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.* It is never good to mix relational operators with bitwise operators. regards, Ranier Vilela

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>> 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, 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.
It is never good to mix relational operators with bitwise operators.
I don't agree with this statement in its generality.
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list
-- Sjoerd Mullender

Em seg., 3 de ago. de 2020 às 12:50, Sjoerd Mullender <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>> 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". regards, Ranier Vilela

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>> 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>>> 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.)
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list
-- Sjoerd Mullender

Em seg., 3 de ago. de 2020 às 13:22, Sjoerd Mullender <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>> 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>>> 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? See: int main () { bool r = true; bool key = true; const char * ptr = "not null"; void * pvoid = NULL; r = (ptr == pvoid); if (r) printf("true\n"); else printf("false\n"); r = ((ptr == pvoid) & key); if (r) printf("true"); else printf("false"); return 0; } Here do not matters key value, always be output is false, be key true or false. See: https://www.gamedev.net/forums/topic/514727-combining-c-bool-and-bitwise-ope... regards, Ranier Vilela

On 8/3/20 7:29 PM, Ranier Vilela wrote: [...]
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)
These two are the same only when the variable b->ttype contains a value different than TYPE_void. But b->ttype might have the value TYPE_void. In that case the whole expression (b->ttype != TYPE_void) & b->tkey evaluates to 0, even if b->tkey is true. If your example program, accepted ptr as input and sometimes it was NULL, while sometimes it was not NULL, that would be a comparable situation.
And if is correct, was that the original intention?
See: int main () { bool r = true; bool key = true; const char * ptr = "not null"; void * pvoid = NULL;
r = (ptr == pvoid); if (r) printf("true\n"); else printf("false\n");
r = ((ptr == pvoid) & key); if (r) printf("true"); else printf("false"); return 0; }
If you set ptr to NULL then the output is true. Likewise b->ttype is not a constant, and that is why we need to check its value. Sometimes that value will be TYPE_void and sometimes it will be different than TYPE_void. You can try to change the bitwise AND to a logical AND in your example program, to see that there is no difference in the computed values. Best regards, Panos.
Here do not matters key value, always be output is false, be key true or false.
See: https://www.gamedev.net/forums/topic/514727-combining-c-bool-and-bitwise-ope...
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list

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.
See: int main () { bool r = true; bool key = true; const char * ptr = "not null"; void * pvoid = NULL;
r = (ptr == pvoid); if (r) printf("true\n"); else printf("false\n");
r = ((ptr == pvoid) & key); if (r) printf("true"); else printf("false"); return 0; }
Here do not matters key value, always be output is false, be key true or false.
See: https://www.gamedev.net/forums/topic/514727-combining-c-bool-and-bitwise-ope...
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list
-- Sjoerd Mullender

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

Sjoerd, Nice explanation, so if they are both correct and one avoids unnecessary work (even just a tiny bit) why not adjust the code to add your explanation as a comment and use the more efficient version? -greg On Mon, Aug 3, 2020 at 3:02 AM Sjoerd Mullender <sjoerd@monetdb.org> wrote:
Either way is correct. 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, 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.
So the difference is whether or not b->tkey is evaluated, and evaluating that is cheap (it's a bool value).
On 01/08/2020 20.54, Ranier Vilela wrote:
Hi,
At gdk\gdk_bat.c (line 1384) variable b->type is bool
Would be a typo? if (((b->ttype != TYPE_void) & b->tkey) && b->batCount > 1) { Should be: if (((b->ttype != TYPE_void) && b->tkey) && b->batCount > 1) {
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list
-- Sjoerd Mullender _______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list

Em seg., 3 de ago. de 2020 às 10:53, Gregory Burd <greg@burd.me> escreveu:
Sjoerd,
Nice explanation, so if they are both correct and one avoids unnecessary work (even just a tiny bit) why not adjust the code to add your explanation as a comment and use the more efficient version?
I'm not sure that is correct. It is the equivalent of writing: if (b->key) Was that the intention of the original author of the code? regards, Ranier Vilela

Hi Ranier, On 8/3/20 4:59 PM, Ranier Vilela wrote:
Em seg., 3 de ago. de 2020 às 10:53, Gregory Burd <greg@burd.me> escreveu:
Sjoerd,
Nice explanation, so if they are both correct and one avoids unnecessary work (even just a tiny bit) why not adjust the code to add your explanation as a comment and use the more efficient version?
I'm not sure that is correct. It is the equivalent of writing: if (b->key)
To see that the code is correct, you can write down the truth table of the *bitwise* AND operator: | b->ttype != TYPE_void | b->tkey || (b->ttype != TYPE_void) & b->tkey | |-----------------------+--------------++-----------------------------------| | false (== 0) | false (== 0) || 0 (== false) | | true (== 1) | false (== 0) || 0 (== false) | | false (== 0) | true (== 1) || 0 (== false) | | true (== 1) | true (== 1) || 1 (== true) | With a little thought you can see that this is the same as the *logical* AND operator. It works because both operands are of type bool, so their values are 0 for false and 1 for true in C99 if you cast them to integral types. (see for example the answers to this Stack Overflow question: https://stackoverflow.com/questions/4767923/c99-boolean-data-type) As Sjoerd wrote in his email the only difference might be a performance penalty in case the first operand is true, if the second operand is expensive to evaluate. This is not the case here because b->tkey is a bool value so its evaluation is cheap. In any case, if you find a particular set of inputs where this (or any other) part of the code produces wrong results we would be interested to see a bug report. Hope this helps, Panos.
Was that the intention of the original author of the code?
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list

Em seg., 3 de ago. de 2020 às 12:18, Panagiotis Koutsourakis < panagiotis.koutsourakis@monetdbsolutions.com> escreveu:
Hi Ranier,
On 8/3/20 4:59 PM, Ranier Vilela wrote:
Em seg., 3 de ago. de 2020 às 10:53, Gregory Burd <greg@burd.me> escreveu:
Sjoerd,
Nice explanation, so if they are both correct and one avoids unnecessary work (even just a tiny bit) why not adjust the code to add your explanation as a comment and use the more efficient version?
I'm not sure that is correct. It is the equivalent of writing: if (b->key)
To see that the code is correct, you can write down the truth table of the *bitwise* AND operator:
| b->ttype != TYPE_void | b->tkey || (b->ttype != TYPE_void) & b->tkey |
|-----------------------+--------------++-----------------------------------| | false (== 0) | false (== 0) || 0 (== false) | | true (== 1) | false (== 0) || 0 (== false) | | false (== 0) | true (== 1) || 0 (== false) | | true (== 1) | true (== 1) || 1 (== true) |
With a little thought you can see that this is the same as the *logical* AND operator. It works because both operands are of type bool, so their values are 0 for false and 1 for true in C99 if you cast them to integral types. (see for example the answers to this Stack Overflow question: https://stackoverflow.com/questions/4767923/c99-boolean-data-type)
As Sjoerd wrote in his email the only difference might be a performance penalty in case the first operand is true, if the second operand is expensive to evaluate. This is not the case here because b->tkey is a bool value so its evaluation is cheap.
In any case, if you find a particular set of inputs where this (or any other) part of the code produces wrong results we would be interested to see a bug report.
int main () { bool r = true; bool key = false; const char * ptr = "not null"; void * pvoid = NULL;
r = (ptr != pvoid); if (r) printf("true\n"); else printf("false\n"); r = ((ptr != pvoid) & key); if (r) printf("true"); else printf("false"); return 0; } output: true true output: true false Always output the key value, be true or false: try: key = true or key = false Again (&) bitwise is not shortcut and only with C++ that bool is guaranted whatever 0 or 1. regards, Ranier Vilela

On 03/08/2020 17.40, Ranier Vilela wrote:
Em seg., 3 de ago. de 2020 às 12:18, Panagiotis Koutsourakis <panagiotis.koutsourakis@monetdbsolutions.com <mailto:panagiotis.koutsourakis@monetdbsolutions.com>> escreveu:
Hi Ranier,
On 8/3/20 4:59 PM, Ranier Vilela wrote: > Em seg., 3 de ago. de 2020 às 10:53, Gregory Burd <greg@burd.me <mailto:greg@burd.me>> escreveu: > >> Sjoerd, >> >> Nice explanation, so if they are both correct and one avoids unnecessary >> work (even just a tiny bit) why not adjust the code to add your explanation >> as a comment and use the more efficient version? >> > I'm not sure that is correct. > It is the equivalent of writing: > if (b->key)
To see that the code is correct, you can write down the truth table of the *bitwise* AND operator:
| b->ttype != TYPE_void | b->tkey || (b->ttype != TYPE_void) & b->tkey | |-----------------------+--------------++-----------------------------------| | false (== 0) | false (== 0) || 0 (== false) | | true (== 1) | false (== 0) || 0 (== false) | | false (== 0) | true (== 1) || 0 (== false) | | true (== 1) | true (== 1) || 1 (== true) |
With a little thought you can see that this is the same as the *logical* AND operator. It works because both operands are of type bool, so their values are 0 for false and 1 for true in C99 if you cast them to integral types. (see for example the answers to this Stack Overflow question: https://stackoverflow.com/questions/4767923/c99-boolean-data-type)
As Sjoerd wrote in his email the only difference might be a performance penalty in case the first operand is true, if the second operand is expensive to evaluate. This is not the case here because b->tkey is a bool value so its evaluation is cheap.
In any case, if you find a particular set of inputs where this (or any other) part of the code produces wrong results we would be interested to see a bug report.
int main () { bool r = true; bool key = false; const char * ptr = "not null"; void * pvoid = NULL;
r = (ptr != pvoid); if (r) printf("true\n"); else printf("false\n");
r = ((ptr != pvoid) & key); if (r) printf("true"); else printf("false"); return 0; }
output: true true
output: true false
Always output the key value, be true or false: try: key = true or key = false
Again (&) bitwise is not shortcut and only with C++ that bool is guaranted whatever 0 or 1.
The first part of the expression was a comparison of a pointer with NULL. An explicit compare operation (here !=) by definition of the C language always results in 0 or 1. And a bool value also, by definition of the C language, evaluates to 0 or 1.
regards, Ranier Vilela
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list
-- Sjoerd Mullender

On 03/08/2020 15.44, Gregory Burd wrote:
Sjoerd,
Nice explanation, so if they are both correct and one avoids unnecessary work (even just a tiny bit) why not adjust the code to add your explanation as a comment and use the more efficient version?
In the one case you have an extra evaluation (of a bit), in the other case you have possibly a jump. If the jump cannot be predicted by the CPU, it is definitely more expensive than the extra evaluation.
-greg
On Mon, Aug 3, 2020 at 3:02 AM Sjoerd Mullender <sjoerd@monetdb.org <mailto:sjoerd@monetdb.org>> wrote:
Either way is correct. 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, 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.
So the difference is whether or not b->tkey is evaluated, and evaluating that is cheap (it's a bool value).
On 01/08/2020 20.54, Ranier Vilela wrote: > Hi, > > At gdk\gdk_bat.c (line 1384) > variable b->type is bool > > Would be a typo? > if (((b->ttype != TYPE_void) & b->tkey) && b->batCount > 1) { > Should be: > if (((b->ttype != TYPE_void) && b->tkey) && b->batCount > 1) { > > regards, > Ranier Vilela > > _______________________________________________ > developers-list mailing list > developers-list@monetdb.org <mailto:developers-list@monetdb.org> > https://www.monetdb.org/mailman/listinfo/developers-list >
-- Sjoerd Mullender _______________________________________________ developers-list mailing list developers-list@monetdb.org <mailto:developers-list@monetdb.org> https://www.monetdb.org/mailman/listinfo/developers-list
_______________________________________________ developers-list mailing list developers-list@monetdb.org https://www.monetdb.org/mailman/listinfo/developers-list
-- Sjoerd Mullender
participants (4)
-
Gregory Burd
-
Panagiotis Koutsourakis
-
Ranier Vilela
-
Sjoerd Mullender