1

Specifically, I am asking about the double '!' in the params of the __built_in.

Is it a double negation, per the 'C' language?

thanks-

user3342339
  • 329
  • 3
  • 18
  • 4
    It can be used to convert any value into a boolean 0 or 1. Ex. `!!(42) == 1` – Colonel Thirty Two Jul 28 '14 at 16:10
  • Related: http://stackoverflow.com/questions/7346929/why-do-we-use-builtin-expect-when-a-straightforward-way-is-to-use-if-else – Mihai Todor Jul 28 '14 at 16:10
  • `if(x)` and `if (__builtin_expect(!!(x), 1))` should reproduce the same order in generated code. Whoever wrote this is doing premature optimization wrong. – Havenard Jul 28 '14 at 16:13
  • 1
    @Havenard actually, it's an optimization for branch prediction. It's saying that `x` is more than likely non-zero, but it might not be. If it's part of a frequently-checked conditional, the extra performance from successful branch prediction can be substantial. – Drew McGowen Jul 28 '14 at 16:15
  • Yes but if it is likely to be non-zero, then `if(x)` will suffice. Looking from assembly perspective the only thing this is doing is converting `x` to either 0 or 1 before `test x,x` instead of doing `test x,x` straight on. May be even inducing the compiler to use `cmp x,1` instead, which is worse. – Havenard Jul 28 '14 at 16:22
  • `if(x)` is a generic test for whether or not `x` is zero. The compiler makes no assumptions as to which value is more likely, thus it must rely on dynamic branch prediction, and may incorrectly guess the first few iterations. However, using `__builtin_expect` will insert a *hint* as to what the initial guess for the branch prediction should be. – Drew McGowen Jul 28 '14 at 16:23
  • Yes it makes no assumption and just generates the code the order you wrote it, with the block for non-zero first, just like this `__builtin_expect` case would do. – Havenard Jul 28 '14 at 16:31
  • I'm not saying `__builtin_expect` is useless, I'm just saying it is not fulfilling its purpose in this particular case. – Havenard Jul 28 '14 at 16:32

1 Answers1

3

The !! is simply two ! operators right next to each other. It's a simple way of converting any non-zero value to 1, and leaving 0 as-is.

Drew McGowen
  • 11,186
  • 1
  • 29
  • 57
  • Thus, it is superfluous in the example (a boolean context). – Deduplicator Jul 28 '14 at 16:50
  • 1
    It's necessary for the given `__builtin_expect`, because it takes two values that are expected to be equal. If it was just `if(x)`, then yes, it would be superfluous. – Drew McGowen Jul 28 '14 at 18:10
  • Say that to the Linux kernel guys: http://stackoverflow.com/questions/109710/likely-unlikely-macros-in-the-linux-kernel Though it looks like they added that later too... – Deduplicator Jul 28 '14 at 20:19