2007-05-25 20:24:20

by Satyam Sharma

[permalink] [raw]
Subject: double exclamation (!!) suckage in the kernel

Hello,

Grepping through the sources I found 500+ occurrences of double
exclamation marks before identifier names (such as !!x -- I took care
to ignore occurrences of !! inside comment blocks, because there
are plenty of that sort too).

!! are to be found even in the definitions of common macros such as
likely() and unlikely(), which hundreds of eyes must have seen over
the last year or so ...

Are all these occurrences merely the debris of
s/something/!notsomething/g kind of patches or is there some
dark, unknown C / gcc wizardry I have absolutely no clue of?

Thanks,
Satyam


2007-05-25 20:29:19

by Russell King

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On Sat, May 26, 2007 at 01:53:59AM +0530, Satyam Sharma wrote:
> Are all these occurrences merely the debris of
> s/something/!notsomething/g kind of patches or is there some
> dark, unknown C / gcc wizardry I have absolutely no clue of?

Try building and running this:

#include <stdio.h>
int main()
{
int i;
for (i = 0; i < 10; i++)
printf("%d: %d\n", i, !!i);
return 0;
}

and you should see it's effect.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of:

2007-05-25 20:33:15

by Satyam Sharma

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On 5/26/07, Russell King <[email protected]> wrote:
> On Sat, May 26, 2007 at 01:53:59AM +0530, Satyam Sharma wrote:
> > Are all these occurrences merely the debris of
> > s/something/!notsomething/g kind of patches or is there some
> > dark, unknown C / gcc wizardry I have absolutely no clue of?
>
> Try building and running this:
>
> #include <stdio.h>
> int main()
> {
> int i;
> for (i = 0; i < 10; i++)
> printf("%d: %d\n", i, !!i);
> return 0;
> }
>
> and you should see it's effect.

Ah, yes, of course I see now!

Thanks!

2007-05-25 20:37:37

by Björn Steinbrink

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On 2007.05.26 01:53:59 +0530, Satyam Sharma wrote:
> Hello,
>
> Grepping through the sources I found 500+ occurrences of double
> exclamation marks before identifier names (such as !!x -- I took care
> to ignore occurrences of !! inside comment blocks, because there
> are plenty of that sort too).
>
> !! are to be found even in the definitions of common macros such as
> likely() and unlikely(), which hundreds of eyes must have seen over
> the last year or so ...
>
> Are all these occurrences merely the debris of
> s/something/!notsomething/g kind of patches or is there some
> dark, unknown C / gcc wizardry I have absolutely no clue of?

It avoids useless warnings. If you have a pointer and want to store if
it is NULL/non-NULL in an integer variables, you have to use !x or !!x.
Just using x will result in a warning that you convert a pointer to an
integer without a cast.

Given this example:

int main()
{
int ret;
void *foo;

ret = foo;
ret = !!foo;

return 0;
}

gcc will emit this warning:
ttt.c:6: warning: assignment makes integer from pointer without a cast

HTH
Bj?rn

2007-05-25 20:41:34

by Al Viro

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On Sat, May 26, 2007 at 01:53:59AM +0530, Satyam Sharma wrote:
> Hello,
>
> Grepping through the sources I found 500+ occurrences of double
> exclamation marks before identifier names (such as !!x -- I took care
> to ignore occurrences of !! inside comment blocks, because there
> are plenty of that sort too).
>
> !! are to be found even in the definitions of common macros such as
> likely() and unlikely(), which hundreds of eyes must have seen over
> the last year or so ...
>
> Are all these occurrences merely the debris of
> s/something/!notsomething/g kind of patches or is there some
> dark, unknown C / gcc wizardry I have absolutely no clue of?

That's a question for a quiz in introductory course on C:
what type should x have for !!x to be a valid expression?
what will be the type of result?
what are the possible values of the result?
describe which values of x correspond to each possible value of !!x

You have 10 minutes (and that's a fairly generous, actually).

2007-05-25 20:56:23

by Satyam Sharma

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On 5/26/07, Al Viro <[email protected]> wrote:
> On Sat, May 26, 2007 at 01:53:59AM +0530, Satyam Sharma wrote:
> > Hello,
> >
> > Grepping through the sources I found 500+ occurrences of double
> > exclamation marks before identifier names (such as !!x -- I took care
> > to ignore occurrences of !! inside comment blocks, because there
> > are plenty of that sort too).
> >
> > !! are to be found even in the definitions of common macros such as
> > likely() and unlikely(), which hundreds of eyes must have seen over
> > the last year or so ...
> >
> > Are all these occurrences merely the debris of
> > s/something/!notsomething/g kind of patches or is there some
> > dark, unknown C / gcc wizardry I have absolutely no clue of?
>
> That's a question for a quiz in introductory course on C:

Ugh ... ok, I've embarrassed myself publicly already, so I'll
also be brave enough to take a C quiz here :-)

> what type should x have for !!x to be a valid expression?

Any integer type (includes pointers)

> what will be the type of result?

int (I guess boolean for C99?)

> what are the possible values of the result?

{0, 1}

> describe which values of x correspond to each possible value of !!x

Russell's mail has already answered that ...

> You have 10 minutes (and that's a fairly generous, actually).

Hmmm, looking through the grep output, actually, it seems some of the
occurrences of !! are indeed debris, but yes, most are actually a way to
force the output to {0, 1} when dealing with individual bits in code.

Satyam

2007-05-25 21:04:13

by Satyam Sharma

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On 5/26/07, Satyam Sharma <[email protected]> wrote:
> On 5/26/07, Al Viro <[email protected]> wrote:
> >
> > That's a question for a quiz in introductory course on C:
>
> Ugh ... ok, I've embarrassed myself publicly already, so I'll
> also be brave enough to take a C quiz here :-)

Hmmm, and now I seem to have flunked ...

> > what type should x have for !!x to be a valid expression?
>
> Any integer type (includes pointers)

gcc doesn't seem to mind a ! on a float either (does it do an implicit
cast to int first?). Can't think of too many situations where one would
want to do a ! on a float, actually, in any case ...

> > what will be the type of result?
>
> int (I guess boolean for C99?)

2007-05-25 21:14:26

by David Miller

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

From: "Satyam Sharma" <[email protected]>
Date: Sat, 26 May 2007 01:53:59 +0530

WHat is with multiple people asking about "!!" all of a
sudden today?

> Are all these occurrences merely the debris of
> s/something/!notsomething/g kind of patches or is there some
> dark, unknown C / gcc wizardry I have absolutely no clue of?

"!!" is used in contexts where pointers might be being
tested as well as plain integers, the "!!" turns a pointer
into the equivalent integer boolean for testing.

NULL pointers become 0
non-NULL pointers become 1

2007-05-25 21:32:21

by Al Viro

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On Sat, May 26, 2007 at 02:26:11AM +0530, Satyam Sharma wrote:
> also be brave enough to take a C quiz here :-)
>
> > what type should x have for !!x to be a valid expression?
>
> Any integer type (includes pointers)

Er, no... Pointers are not integer types *and* you can use ! on any
scalar type (including floating ones, even though it's not particulary
useful there).

> > what will be the type of result?
>
> int (I guess boolean for C99?)

Actually, ! and comparisons still give int in C99 (and !x is defined as
(x == 0) in all situations).

2007-05-25 21:36:57

by Al Viro

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On Fri, May 25, 2007 at 10:32:13PM +0100, Al Viro wrote:
> On Sat, May 26, 2007 at 02:26:11AM +0530, Satyam Sharma wrote:
> > also be brave enough to take a C quiz here :-)
> >
> > > what type should x have for !!x to be a valid expression?
> >
> > Any integer type (includes pointers)
>
> Er, no... Pointers are not integer types *and* you can use ! on any
> scalar type (including floating ones, even though it's not particulary
> useful there).

... which means that original question ("what type should x have...")
gets the answer "scalars, arrays or functions". The last two variants
give you constant 1, though (arrays and functions decay to pointers in
such context and that pointer is not going to be different from null
pointer of the same type; thus you get !!x => !0 => 1).

2007-05-25 21:37:31

by Satyam Sharma

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On 5/26/07, Al Viro <[email protected]> wrote:
> On Sat, May 26, 2007 at 02:26:11AM +0530, Satyam Sharma wrote:
> > also be brave enough to take a C quiz here :-)
> >
> > > what type should x have for !!x to be a valid expression?
> >
> > Any integer type (includes pointers)
>
> Er, no... Pointers are not integer types *and* you can use ! on any
> scalar type (including floating ones, even though it's not particulary
> useful there).

Yeah, I noticed this (with a sample program) just after the quiz ...

> > > what will be the type of result?
> >
> > int (I guess boolean for C99?)
>
> Actually, ! and comparisons still give int in C99 (and !x is defined as
> (x == 0) in all situations).

Hmm, thanks for explaining this.

Satyam

2007-05-26 13:42:19

by Jan Engelhardt

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel


On May 25 2007 14:14, David Miller wrote:
>
>WHat is with multiple people asking about "!!" all of a
>sudden today?
>
>> Are all these occurrences merely the debris of
>> s/something/!notsomething/g kind of patches or is there some
>> dark, unknown C / gcc wizardry I have absolutely no clue of?
>
>"!!" is used in contexts where pointers might be being
>tested as well as plain integers, the "!!" turns a pointer
>into the equivalent integer boolean for testing.
>
>NULL pointers become 0
>non-NULL pointers become 1

Though,
if(!!ptr)
is effectively the same as
if(ptr)

!! is mostly used where non-zero values need to be mapped to 1.
Not so much in logic expressions (if,while,etc.) but in arithmetic
(who'd do that?).

Jan
--

2007-05-26 16:38:27

by Bodo Eggert

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

Jan Engelhardt <[email protected]> wrote:
> On May 25 2007 14:14, David Miller wrote:

>>"!!" is used in contexts where pointers might be being
>>tested as well as plain integers, the "!!" turns a pointer
>>into the equivalent integer boolean for testing.
>>
>>NULL pointers become 0
>>non-NULL pointers become 1
>
> Though,
> if(!!ptr)
> is effectively the same as
> if(ptr)

Not exactly, if(foo) is the same as if( (int) foo), which is not
guaranteed to result in non-null values for non-null pointers.
ISO 9899/1999 says: "Any pointer may be converted to an integer type. [...]
The result need not be in the range of values of any integer type."

"if(!!foo)" is the same as "if(0 == (0 == foo))", which is (I asume) the same
as "if(0 == ((type_of_foo)NULL == foo))", or if((type_of_foo)NULL != foo).
--
Funny quotes:
11. Atheism is a non-prophet orgainization.

Fri?, Spammer: [email protected] [email protected]

2007-05-26 16:50:27

by Al Viro

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On Sat, May 26, 2007 at 06:38:07PM +0200, Bodo Eggert wrote:
> Not exactly, if(foo) is the same as if( (int) foo), which is not
> guaranteed to result in non-null values for non-null pointers.

RTFStandard.

> ISO 9899/1999 says: "Any pointer may be converted to an integer type. [...]
> The result need not be in the range of values of any integer type."

... and it sure as hell does *NOT* say that controlling expression of
if statement is converted to an integer type. For pointers of for anything
else. if (v) is the same as if (v != 0) [6.8.4.1p2], and if v is a pointer,
0 in that comparison becomes a null pointer constant [6.5.9p5].

2007-05-29 08:27:17

by Bodo Eggert

[permalink] [raw]
Subject: Re: double exclamation (!!) suckage in the kernel

On Sat, 26 May 2007, Al Viro wrote:

> On Sat, May 26, 2007 at 06:38:07PM +0200, Bodo Eggert wrote:
> > Not exactly, if(foo) is the same as if( (int) foo), which is not
> > guaranteed to result in non-null values for non-null pointers.
>
> RTFStandard.

... and don?t forget half of it untill you look up the next thing.
Yes, obviously I misremembered "compares equal to" as "is".