Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 794 Vote(s) - 3.54 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why the linux kernel uses double logical negations instead of casts to bools?

#1
Given that `x` is a variable of type `int` with the number `5` as its value, consider the following statement:

int y = !!x;

This is what I think it happens: `x` is implicitly casted to a `bool` and the first negation is executed, after that the last negation is made, so a cast and two negations.

My question is, isn't just casting to bool (executing `int y = (bool)x;` instead of `int y = !!x`) faster than using double negation, as you are saving two negations from executing.

I might be wrong because I see the double negation a lot in the Linux kernel, but I don't understand where my intuition goes wrong, maybe you can help me out.
Reply

#2
> The only reason I can imagine is because this saves some typing (7 chars vs 2 chars).

**As @jwdonahue and @Gox have already mentioned, this is not the correct reason. C did not have bool when the linux kernel was written therefore casting to bool was not an option.**

As far as efficiency goes, both are equivalent because compilers can easily figure this out. See

[To see links please register here]


bool cast_to_bool_1(int x) {
return !!x;
}

bool cast_to_bool_2(int x) {
return (bool) x;
}

Both the functions compile to the same assembly which uses the `test` instruction to check if the argument is zero or not.

test edi, edi // checks if the passed argument is 0 or not
setne al // set al to 0 or 1 based on the previous comparison
ret // returns the result
Reply

#3
There was no bool type when Linux was first written. The C language treated everything that was not zero as true in Boolean expressions. So 7, -2 and 0xFF are all "true". No bool type to cast to. The double negation trick ensures the result is either zero or whatever bit pattern the compiler writers chose to represent true in Boolean expressions. When you're debugging code and looking at memory and register values, it's easier to recognize true values when they all have the same bit patterns.

Addendum: According the [C89 draft standard](

[To see links please register here]

), [section 3.3.3.3](

[To see links please register here]

):

> The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int . The expression !E is equivalent to (0==E).

So while there was no Boolean type in the early days of the Linux OS, the double negation would have yielded either a 0 or a 1 (thanks to [Gox](

[To see links please register here]

) for pointing this out), depending on the truthiness of the expression. In other words any bit pattern in the range of `INT_MIN..-1` and `1..INT_MAX` would have yielded a 1 and the zero bit pattern is self-explanatory.
Reply

#4
`C` language unlike other languages does not have `bool` type. `bool` in `C` is actually defined in `stdbool.h` which is not included in many `C` projects. Linux kernel is one such projects, it would be a pain to go through Linux code and update everything to use `bool` now as well. That is reason why Linux kernel does not use `bool` in `C`.

why `!!x`? This is done to ensure that value of `y` is either `1` or `0`. As an example if you have this cocd

x=5;
int y = !!x;

We know that everything that non-zero values in `C` mean true. So above code would brake down to `y= !!(5)` followed by `y = !(0)` and than `y = 1`.

EDIT:
One more thing, I just saw OP mentioned casting to `bool`. In `C` there is no `bool` as base type, `bool` is defined type, thus compilers do not cast integers to Boolean type.

EDIT 2:
To further explain, in `C++`, `Java` and other languages when you type `bool a = false` you do not have to use headers or compile some other libraries or define `bool` type for `bool` type to work, it is already incorporated into compilers, where as in c you have to.

EDIT 3:
`bool` is not the same as `_Bool`.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through