using "!!" in "c"

M

markryde

Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
MR
 
Z

Zara

Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
MR


It is "not not", thta is, it checks its argument to see if it is not
zero.

Is is a way to make explicit that the argument is not a bool, and is
being tested for a non-zero value.

Zara
 
N

Nick Keighley

Zara said:
On 18 Jan 2006 01:28:23 -0800, (e-mail address removed) wrote:

It is "not not", thta is, it checks its argument to see if it is not
zero.

Is is a way to make explicit that the argument is not a bool, and is
being tested for a non-zero value.

no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-

x !x !!x
0 1 0
1 0 1
2 0 1

where "2" represents an arbitary non-zero value
 
N

Nick Keighley

oops! my previous post should have been addressed to Raguath not Zara.
It then would have read something like this:-



oh, and leave some context in your posts
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

August said:
You're wrong, it is an operator ;-)

IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"


- --

Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFDznCpagVFX4UWr64RAkxUAJ4nCK7v7Oj0faWIPdx22S3B1xTkqgCg8LDh
v4QqWYNHcdtp7g6yosbiZNo=
=x7SK
-----END PGP SIGNATURE-----
 
P

pemo

Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?
MR

!! is a good way of turning a scalar value into 1 or 0.

For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300

However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'

I've seen/used !! in functions that allocate memory, and return 1 if the
memory was allocated ok, else 0.

A routine like this would look something like ...

void * p;

int allocStuff(size_t n)
{
p = malloc(n);

return !!p;
}

int main(void)
{
if(allocStuff(...))
{
}
else
{
}
}

Although the code above would work if allocStuff simply returned the actual
pointer value, it would stop someone from finding out that fact, and doing
something like this ...

int main(void)
{
void * p1;

if(p1 = allocStuff(...))
{
// Aha, we've now got a pointer to the memory allocated!!!
}
else
{
}
}

Yes, in the code above [first], you'd also get the same thing by accessing
p, but I hope you get the gist of this simple example, and see how it could
be extended?
 
C

Craig Taylor

Nick said:
no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-

x !x !!x
0 1 0
1 0 1
2 0 1

where "2" represents an arbitary non-zero value

You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2 or
anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true

- Craig Taylor
http://www.ctalkobt.net
 
K

Keith Thompson

Lew Pitcher said:
IIUC, ragnauth.cr /meant/ to say

! is "not" operator.

as in
! is the operator for "logical not"

Right, which is why Lew used the ";-)" operator.
 
K

Keith Thompson

pemo said:
!! is a good way of turning a scalar value into 1 or 0.

So is (value, 0) (i.e., a comma operator). It turns a scalar value
into 1 or 0. It just happens to be 0.

!! maps 0 to 0, and any non-zero value to 1, for any scalar operand.
For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300

It will output some implementation-specific sequence of printing
characters. The sequence may or may not look like a number.
However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'

That invokes undefined behavior.

"boo" yields a char* value. The "!" operator yields 1 if its operand
compares equal to 0, 0 otherwise. In this case, it compares the char*
value to a null pointer value. Since "boo" cannot be a null pointer,
!"boo" is guaranteed to yield 0. Applying "!" again yields the int
value 1.

So the above is equivalent to

printf("%p\n", (void*)1);

The conversion of the int value 1 to void* may yield a trap
representation; passing this to printf() (or doing anything else with
it) invokes undefined behavior.
I've seen/used !! in functions that allocate memory, and return 1 if the
memory was allocated ok, else 0.

A routine like this would look something like ...

void * p;

int allocStuff(size_t n)
{
p = malloc(n);

return !!p;
}

That's fine, since !!p is an int value and the function returns an int.

The thing to remember is that !!foo doesn't just normalize foo to 0 or
1; it yields a value of type int, regardless of the type of foo.
 
M

Mike Wahler

Hello,
I saw in some open source projects a use of "!!" in "C" code;
for example:
in some header file
#define event_pending(v) \
(!!(v)->vcpu_info->evtchn_upcall_pending & \
!(v)->vcpu_info->evtchn_upcall_mask)

whereas evtchn_upcall_pending is of type unsigned char
(and also evtchn_upcall_mask is of type unsigned char).

What does "!!" operator do in this case ? Any ideas?

There is no "!!" operator. What you are seeing is
two adjacent "!" (logical 'not') operators. In a
Boolean context, any zero value is considered 'false',
any nonzero value, 'true'. C's explicit values for
reporting (e.g. with 'if()') 'true' and 'false' are
zero (0) and one (1) respectively.


0 == 0
!0 == 1
!!0 == 0

1 == 1
!1 == 0
!!1 == 1

42 == 42
!42 == 0
!!42 == 1


!! is sometimes used to convert a true (but not == 1)
value to 1.

-Mike
 
K

Keith Thompson

Craig Taylor said:
Nick Keighley wrote: [...]
no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-
x !x !!x
0 1 0
1 0 1
2 0 1
where "2" represents an arbitary non-zero value

You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2
or anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true

No, Craig's table is correct and is more precise than yours. The "!"
operator yields a value of type int; that value is guaranteed to be
either 0 or 1.

All C operators that yield logical values:
&& || ! == != < <= > >=
always yield a value of either 0 or 1. If any of them yield a
non-zero value other than 1, your compiler is buggy.

It's probably bad style to rely on this unless you have a specific
reason to do so.

All contexts that require a condition:
if()
while()
for(...;condition;...)
do while()
condition ? ... : ...
condition && condition
condition || condition
! condition
treat zero as false, and any non-zero value as true.

A *function* that returns a logical value (as type int) can reasonably
return any non-zero value for true; for example, the is*() functions
in <ctype.h> are allowed to do this.
 
C

Craig Taylor

Keith said:
Right, which is why Lew used the ";-)" operator.

;-) is an operator? I've never seen it before. Is this a C99 extension?

Does it modify the line of code that it's on to perform what you meant
it to do instead of how you coded it for? If so, I've been looking for
that for a while. (This may also explain why there's few C99 compilers
around... ). ;-)

- Craig Taylor
http://www.ctalkobt.net
 
C

Chris Torek

You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2 or
anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true

C distinguishes clearly between "input" and "output" logical values
for its logical operators (!, ||, &&): on input, any nonzero value is
true and zero is false, but on output, true is exactly 1.

Note that not all "apparently logical" functions are necessarily
logical functions, e.g., isspace() and so on from <ctype.h> do not
necessarily produce only 0-or-1.

See also <http://www.c-faq.com/bool/bool2.html>.
 
M

Mark B

Keith Thompson said:
Craig Taylor said:
Nick Keighley wrote: [...]
no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-
x !x !!x
0 1 0
1 0 1
2 0 1
where "2" represents an arbitary non-zero value

You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2
or anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true

No, Craig's table is correct and is more precise than yours.

Newsreader problem Keith?
Would have let it slide, but this is the 2nd post of yours I've
read in the last minute which improperly attributes quoted text.
Nick's table is the one you are claiming is more precise...
Craig's table is the one you are complaining about.

(note: the other attribution was further up thread...
August was the one who used the ";-)" operator, not Lew)
 
F

Flash Gordon

pemo said:
!! is a good way of turning a scalar value into 1 or 0.
Yes.

For example, this

printf("%p\n", (void *)"boo");

will output some value that's not 0, and very unlikely to be 1, e.g.,
0040300
Fine.

However, this

printf("%p\n", (void *)!!"boo");

will output 000001, e.g., '1'

Or almost anything else since the conversion from integer to pointer is
implementation defined. If you want something like that do:
printf("%d\n", !!"boo");

<snip>
 
K

Keith Thompson

Mark B said:
Keith Thompson said:
Craig Taylor said:
Nick Keighley wrote: [...]
no, not really. In C a non-zero value is taken to be true. "!" as you
state is the not operator and yields either 0 (false) or 1 (true). So
"!!"
yeilds a "normalised" boolean value that is it has the same logical
value but is guaranteed to be 0 or 1. Using a truth table:-
x !x !!x
0 1 0
1 0 1
2 0 1
where "2" represents an arbitary non-zero value

You make reference to it but your table doesn't reflect that C simply
defines logical true as non zero so you can't say that it's == 1 or 2
or anything - only that it's non-zero.

More precisely:
x !x !!x
0 1 0 ie: logical false
1 0 != 0 ie: logical true
2 0 != 0 logical true

No, Craig's table is correct and is more precise than yours.

Newsreader problem Keith?

Yes. Not the software, just the guy at the keyboard reading the news.
Would have let it slide, but this is the 2nd post of yours I've
read in the last minute which improperly attributes quoted text.
Nick's table is the one you are claiming is more precise...
Craig's table is the one you are complaining about.

(note: the other attribution was further up thread...
August was the one who used the ";-)" operator, not Lew)

My apologies, and thanks for catching my errors.
 
A

August Karlstrom

Craig said:
;-) is an operator? I've never seen it before. Is this a C99 extension?

Does it modify the line of code that it's on to perform what you meant
it to do instead of how you coded it for? If so, I've been looking for
that for a while. (This may also explain why there's few C99 compilers
around... ). ;-)

So you haven't heard about it? It's called the ironic statement
terminator. It's mostly used by expert C programmers writing programs
intended to be read by other experts. For instance

x = 5;-)

adds some interesting uncertainty to the statement `x = 5;'. These
people find the preciseness of the latter statement boring. The only way
to be sure of what an ironic statement really means is to get to know
the author really well.


August
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top