tags:

views:

321

answers:

4
+5  Q: 

What is !0 in C?

I know that in C, for if statements and comparisons FALSE = 0 and anything else equals true.

Hence,

int j = 40
int k = !j

k == 0 // this is true

My question handles the opposite. What does !0 become? 1?

int l = 0
int m = !l

m == ? // what is m?
+1  A: 

Generally, yes, it'll become 1. That said even if that is guaranteed behavior (which I'm not sure of) I'd consider code that relied on that to be pretty awful.

You can assume that it's a true value. I wouldn't assume anything more.

Steven Schlansker
Not just generally; *always*. Boolean operators in C are required to return either 0 or 1.
jamesdlin
Still, it feels like a violation of having your code show intent.
Steven Schlansker
Not at all. Things like `prefix="-"+!neg;` are perfectly sane C.
R..
@R..: I'd not seen that one before. If neg is false, it points to the null byte at the end of the string? Cuter than having prefix be a char which is either 45 or 0, and having the display routine filter out null bytes).
supercat
Yeah, if `neg` is false then `prefix` points to an empty string. If it's true, `prefix` points to the string `"-"` (with null termination either way, of course).
R..
+1  A: 

The Bang operator (!) is the logical not operator found commonly in C, C++ and C#, so

!0 == 1
!1 == 0

This is based on the language characteristic of what is interpreted to be either true or false... in more modern languages it would be like this

!false == true
!true == false

See DeMorgan Law concerning truth tables...

tommieb75
Actually, in C++, `!` takes a `bool` operand and produces a `bool` result -- though for backward compatibility, there are implicit conversions from `bool` to `int`, with `true` converting to `1` and `false` to `0`, and from other integer types to `bool`, with `0` converting to `false`, and any other value converting to `true`.
Jerry Coffin
+20  A: 

Boolean/logical operators in C are required to yield either 0 or 1.

From section 6.5.3.3/5 of the ISO C99 standard:

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.

In fact, !!x is a common idiom for forcing a value to be either 0 or 1 (I personally prefer x != 0, though).

Also see Q9.2 from the comp.lang.c FAQ.

jamesdlin
Good call. Looks like more of us need to actually read the damn ISO Standard.
Justin Niessner
+1 for pointing to the standard, but code that uses `!!` needs to head straight to the garbage can.
Billy ONeal
This should be the accepted answer.
Stephen Canon
Of course not a lot of C compilers feel particularly compelled to follow the ISO standard. GCC probably, but with anyone else its a crapshoot.
T.E.D.
@Stephen Canon - Well, vote it up enough and he'll at least get the Populist badge. It's a gold too.
T.E.D.
Please link to the ISO standard, so that we too can look it up sometimes.
BiGYaN
GCC, ICC, clang, the IBM and HP compiler tools all make a good faith effort to follow the standard. I'm sure I'm forgetting some others. MSVC is the only compiler I've encountered that doesn't at least *try* to follow the standard.
Stephen Canon
@T.E.D.: Sadly, the accepted answer needs to have at least 11 votes for him to get populist.
Stephen Canon
@BiGYaN: AFAIK the C standard must be purchased, and I am not aware of a legitimate, free version that I could link to. Also see http://c-faq.com/ansi/avail.html
jamesdlin
Curious: Is this true in C89?
mathepic
@mathepic: Yes, it's true for C89 as well (section 6.3.3.3).
jamesdlin
@Billy ONeal: To my mind, saying "flagvar = !!(multibitFlag " is clearer than "flagvar = ((multibitFlag " What is gained by the extra verbosity of the latter format?
supercat
RBerteig
@supercat: What is gained is the clarity of the code. `!!` is trying to be tricky, `!= 0` explains explicitly to the reader what the code is doing. However, in that case, there's no reason for the `!!` or `!=` at all.
Billy ONeal
@Billy ONeal: `!!` is perfectly clear to an experienced C programmer, since it's the idiomatic way of flattening a value to 1 or 0. `!= 0` is no better since it relies on knowing that the result of the `!=` operator is either 1 or 0, as opposed to the `!` operator. In fact I'd argue that it's worse, since `!!` more clearly conveys the intent. If you want a better alternative, I suggest `? 1 : 0`.
caf
Or use a C99 toolchain, `#include <stdbool.h>` and cast to `bool`.
Stephen Canon
@Stephen Canon: Is a cast of any numeric type to "bool" guaranteed to convert any non-zero value to 1? Some compilers I use have a "bit" type which behaves as a one-bit integer (so assignments just use the LSB of the source operand).
supercat
@Billy ONeal: I find the "!!" format more readable, since there's less stuff to visually parse, and to my mind the concept of "nonzero" is distinct from the concept of "doesn't equal the numerical constant zero". And there is a reason for the "!!": if multiBitFlag grows to be bigger than flagVar, the "!!" ensures the result will fit. It's also often nicer for routines' contracts to indicate that they'll return 1 or 0, rather than just some arbitrary non-zero value or zero (though I know that e.g. strcmp etc. merely specify the sign of their results, and not the value).
supercat
@supercat: "When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1." (§6.3.1.2)
Stephen Canon
jamesdlin
+3  A: 

§6.5.3.3/5: "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 other logical operators (e.g., &&, ||) always produce either 0 or 1 as well.

Jerry Coffin