How does logical negation work in C? - c

I have been using ! (logical negation) in C and in other languages, I am curious does anyone know how to make your own ! function? or have a creative way of making one?

int my_negate(int x)
{
return x == 0 ? 1 : 0;
}

!e can be replaced by ((e)?0:1)

Remember the bang operator '!' or exclamation mark in english parlance, is built into the programming language as a means to negate.
Consider this ternary operator example:
(some condition) ? true : false;
Now, if that was negated, the ternary operator would be this
(some condition) ? false : true;
The common area where that can get some programmers in a bit of a fit is the strcmp function, which returns 0 for the strings being the same, and 1 for two strings not the same:
if (strcmp(foo, "foo")){
}
When really it should be:
if (!strcmp(foo, "foo")){
}
In general when you negate, it is the opposite as shown in the ternary operator example...
Hope this helps.

C considers all non-zero values "true" and zero "false". Logical negation is done by checking against zero. If the input is exactly zero, output a non-zero value; otherwise, output zero. In code, you can write this as (input == 0) ? 1 : 0 (or you can convert it into an if statement).
When you ask how to "make your own ! method", do you mean you want to write a function that negates a logic value or do you want to define what the exclamation-point operator does? If the former, then the statement I posted above should suffice. If the latter, then I'm afraid this is something that can't be done in C. C++ supports operator overloading, and if doing this is a strict necessity then I would suggest looking there.

If you want to overload an operator, the proper prototype is:
bool operator!();
I'm not a big fan of overloading operators, but some people like their syntactic sugar.
EDIT: This is C++ only! Put it in the definition of your class.

Related

-Wint-in-bool-context warning issue in some compilers

I am a getting warning:
warning: '<<' in boolean context, did you mean '<' ? [-Wint-in-bool-context]
for the code similar to the following:
int a=7,b=3;
int index=((a<<1)||b)&&5;
To explain the rationale behind such warnings:
C did get a boolean type _Bool/bool as per C99, but no changes were done to the behavior of the various logical operators of the language. That is:
Equality operators ==/!=
Relational operators <,<=,>,>=
Logical AND &&
Logical OR ||
Logical negation !.
Despite C having a boolean type, all of these operators return type int with value 1 or 0. Unlike C++ where all of these operators actually return type bool with value true/false. This is a known flaw of C.
It's common good practice however to treat such expressions as if they were boolean. Coding guidelines like MISRA C encourage the use of a fictional type "essentially boolean", meaning any expression that could be treated as _Bool. The reason for this is that it makes code more self-documenting and also makes it harder to create various typo-related bugs.
For example if(str) could mean check for NULL, or it could mean check for null termination but oops we forgot to dereference. Same thing with if(*str). Whereas if we only pass the result of a logical operator to if, the code becomes much clearer and it becomes harders to write bugs: if(str != NULL) could only mean check for NULL and if(*str != '\0') could only mean check for null termination.
In your case, the || operator only cares if the operands are zero or non-zero ("essentially boolean"). In case a is non-zero then a<<1 will not change that. In case a is zero, then a<<1 is zero as well. Since the result is passed on to a logical operator, "in a boolean context", the shift is pointless - hence the warning. But of course a<<1 might take all kinds of other values in another context such as for example if(a<<1 & mask).
It would be reasonable to strongly suspect that you actually meant to write a<1 instead. Because that would yield either 0 or 1, where < is also a logical operator like ||.
I got the solution. We should avoid integers using with logical operators (eg. ||,&&). Using integers with bitwise operators (eg. <<,&,|,etc.) is fine.
Sometimes we don't get this problem while running on compilers because of low priority warning filters. In complex and warning sensitive compilers it comes up.
Thanks

Why does the logical statement !0x00 return 0x01 in C?

I'm reading Computer Systems a programmers perspective, and I'm getting into logical operators, which are similar to bitwise operators, but with a few differences.
What I CANNOT figure out is that when you have a logical operand !0x00 returns 0x01 rather than 0x11?
! is NOT, right? So NOT 0(false) should be 1(true) and another NOT 0(false) should also be 1(true) as well, right?
I look at the bitwise operator example : ~00, naturally that would return 11, but C's logical operators seem to work with vast differences.
Why does this happen?
What I have tried already: Reading a little further to find the answer I seek, it doesn't seem to be here.
What I think the problem is: Might have something to do with how Hexadecimals work? But, Hexadecimals can still have 0x11. . . .
Because that's how the language is defined. ! is the logical NOT operator and boolean logic in C works on 1 and 0, representing true and false.
C17 6.5.3.3:
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.
You can think of it as if returning bool, though it actually returns int for backwards-compatibility reasons. Unlike C++ where it does return bool. The same goes for relational and equality operators.
The expression !n is equivalent to (n==0). It returns 1 if true, 0 if false.
Neither !0x00 nor ~0x00 will give you 0x11.
!n is the same as n==0 and evaluates to 1 or 0.
~n negates the bits of the binary representation, not the digits of the literal you chose to enter the number.

Bitwise AND operation on boolean values in C [duplicate]

I had the need to code a statement of the form
a = a || expr;
where expr should be evaluated and the result be assigned to a iff a is not set. this relies on the logical OR's short-circuiting capabilities.
The shorter way to write the above would, of course, be
a ||= expr;
but (to my surprise) C does not have logical assignment operators.
So my question is twofold. First, is there a shorter way to write the first statement in standard C (the ternary operator is even worse - a = a ? a : expr requires me to spell out a thrice).
Secondly, why aren't there logical assignments in C? The possible reasons I could think of are:
it makes the grammar harder to parse?
there is some subtlety in handling short-circuiting for these cases?
it was considered superfluous (but isn't that an argument against ALL the operator assignments?)
EDIT
Please unlock this question because:
The question it has been linked to (as a alleged duplicate of) HAS NOT BEEN ANSWERED. The (accepted) answer to that question states that ||= is not present because duplicates the functionality of |=. That is the wrong answer. |= does not short-circuit.
C and C++ are NOT the same languages. I wish to know why C doesn't have it. In fact, the fact that derived languages like C++ and, particularly, Java (which did not suffer from the problems of legacy code as has been suggested in Edmund's answer) makes the question even more interesting.
EDIT 2
It now seems like my original intent was wrong. In the statement a = a || expr (where a is integral and expr returns an integral value, first both a and expr will be implicitly converted to "booleans", and then the "boolean" value will be assigned to a. This will be incorrect — the integral value will be lost. Thanks, Jens and Edmund.
So for the first part of the question, the correct ways, not alternatives :), to code my intention would be:
if (!a) a = expr;
or
a = a ? a : expr;
they should be optimized the same (I think) though personally I would prefer the first one (because it has one less a to type).
However, the second part of the question still remains. The arguments that Jens and Edmund about have given about the ambiguity in a ||= expr apply equally well to a = a || expr. the assignment case can simply be treated as the normal one:
convert a to boolean
if it is true, the value of the entire expression becomes equal to the boolean value of a
otherwise evaluate expr, convert result to boolean, assign to a, and return it
The steps above seem to be the same for both the assignment and normal case.
a ||= expr is problematic due to short circuit evaluation of its equivalent a = a || expr.
To have a ||= expr function like a = a || expr consider OP's assertion:
"In the statement a = a || expr ..., first both a and expr will be implicitly converted to "booleans","
This is not quite correct. expr will not be converted if a evaluates to true. This would make a difference should expr be something like scanf() or rand() or some function that affected the state of the program.
Code such as a ||= scanf("%d", &i) != 1; would only attempt to scan data with a false value in a. Although it would be possible to extend the language this way, additional short-circuit operators to the current set of || and && would likely cause more coding problems than clear simplifications.
On the other hand: A quick, if obfuscated, way to write code where functions return non-zero codes on error.
// Perform functions until an error occurs.
bool error = foo1();
error &&= foo2(); // Only valid if C was extended with &&=
error &&= foo3();
Because the return type of operators || and && is not the same as type of their left argument.
The return type of || and && is always int1, while the left argument may be any integral, floating point or pointer type. The operands also don't have to be of the same type. Therefore defining x ||= y as x = x || y and x &&= y as x = x && y as would be consistent with other augmented assignments would not be able to store the result in the argument for most types.
You could come up with other definitions, e.g. x ||= y as if(!x) x = y and x &&= y as if(!y) x = y, but that would not be exactly obvious and it is not that useful, so it was not included.
1In C++ it is bool.
I guess the simple answer is that || is a boolean operator: and in C, a "boolean" is 0 or 1. The operands are implicitly converted to booleans (I have not checked that that's what the spec actually says, but it's how C behaves), and the result is a boolean.
Altering the semantics to support this pattern may well be feasible -- until someone relies on || doing what it's always done.
I cannot find any particular reason, why the operators don't exist (in C99).
So the only reason I can find is, that there was no boolean type in C89, and those boolean operators were intended to be solely used in if's.
Example:
int i = 5;
/* This should not make any difference,
since or'ing with false, shouldn't change
the value... dib di dib diddy...*/
i ||= 0; /* Actually: i = i || 0, which gives 'true' */
i is now '1'', which for most people is pretty counter intuitive.
This operator obviously doesn't bring any clearence or coding improvement without the boolean type, that would make sence being or'd with another one.
In my opinion, the implementation of a ||= b; as if(!a) a = b; would be pretty straightforward and has aleardy been implemented by e.g. Lua.
So you're question seems to be a bit, why C has been designed the way it has been designed.
If this question was about C++, you could for example ask Bjarne Stroustrup and ask him, what had went into him. Since this is not the case, this seems to me to be kind of a dead end, because the standard has been written quite some time ago and you cannot really ask people anymore, why the h***.
On the other hand, this incomplete operator set should (in my opinion) aleardy have been made whole using a similar notation than yours, since in my opinion, there is no reason against it.
I hope I could help a little.
One simple explanation is this.
bool resultsComputeAll = false;
bool resultsUntilFirst = false;
for (int i = 0; i < 10; ++i) {
resultsComputeAll = compute(i) || resultsComputeAll;
resultsUntilFirst = resultsUntilFirst || compute(i);
}
Which one would be result ||= compute(i)? It's ambiguous so it's better to not define.

Logical equality in C

[It seems odd this doesn't exist, so apologies in advance if it's a duplicate]
I want to test for logical equality in C. In other words, I want to know whether two values would be equal if both were converted in the normal way associated with logical expressions.
In C99, I think that
(bool)a == (bool)b
gives what I want. Is that correct? What is the normal way of writing this in traditional C?
You typically see this:
if ((a == 0) == (b == 0))
Or
if (!!a == !!b)
Since !!a evaluates to 1 if a is nonzero and 0 otherwise.
Hope this helps!
In C, zero is false. If you want to convert any value to its boolean equivalent, the standard way (well, except that there's almost never a need for it) is to prefix an expression with !! , as in !!a. In the case of your expression,
!!a == !!b
may be simplified to
!a == !b
In pre-C99 C, the tradiitional, idiomatic way to "cast to bool" is with !!.
There is no (bool) in traditional c. True/False is handled using ints. You can check for boolean equality with
a ? b : !b

Question about C ! operator

My understanding of this is as follows. In C, the ! operator returns 0 if it is given a nonzero value and returns a nonzero value if it is given 0.
Say you have this little snippet of C code:
int y = 0;
int z = !y;
What value will go into z? Does it simply take !0 to be 1? Is it system dependent? Does the C standard dictate what is supposed to happen? I ran into these questions while doing some homework earlier tonight dealing with bitwise 2's-complement integer manipulation. I got a certain problem to work, but I'm sort of scratching my head as to why it works. Thanks a lot for any info!
Truth values "generated by" C are always 0 or 1.
It is true (heh) that a non-zero expression is generally considered "true" in if and so on, but when the language itself needs to generate a truth value it uses 0 for false and 1 for true.
Since the ! operator is a logical operator, it will always result in 0 or 1.
So in your case, z will be set to 1.
Update: See this FAQ entry for more discussion, that's what I had in mind with the "generated by" wording. Amazingly, it even has the same pun (I did not look this entry up before writing my answer). Not sure if this is an indication of me having a good sense of humor, or not.
The result of an unary-expression with the ! operator is an int with value 0 or 1.
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).
From The C Standard (n1124) section 6.5.3.3.

Resources