Monday, September 21, 2009

c: double exclamation

Linux kernel is full of fascinating code. Not all of it is good but it's possible to find something interesting.
While reading the kernel code I've seen a lot of conditional expressions that contain double exclamations. Something like:

if (!!smth) {...}
I was curious what's the purpose of such expression.
And I've found that mostly this is used to make compiler happy and quite. Double exclamation or simply '!!' turns the expression value into binary representation: either '1' or '0'. Everything that could be treated as true results into '1' otherwise - '0'.
The simplest example to show it in action could be:
int i;

for (i = 0; i < 5; i++)
    printf("%d: %d\n", i, !!i);
This will print to the output:
0: 0
1: 1
2: 1
3: 1
4: 1
So, which compiler warnings this could help to suppress? That's very easy. Let's assume there's a function like following:
int function(void)
{                                                                                                     void *ptr;
    /* Useful calculations */
    return ptr;
The compiler, at least gcc, will warn that return expression makes integer from pointer without a cast. If function should return '1' on success and '0' on failure, double exclamation fits very well:
int function(void)
{                                                                                                     void *ptr;
    /* Useful calculations */
    return !!ptr;
Besides this simple example the double exclamation expression has indeed wide range of application.


LatinSuD said...

I think a good use of !! is to sanify a boolean.
In C integers and booleans are quite the same, everything non-zero is considered "true", but sometimes you may want to canonify the value to be strictly 0 or 1.

AnkitRocks2008 said...