This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Double Negation in C++ code
Let's say:
bool var = !!true;
It will assign "true" to the variable. Seems useless, but I was looking at Visual Studio's definition of "assert", and it is:
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
Why does it negate the "_Expression" twice?
I wonder that they want to force the "!" operator to be called (in the case it is overloaded), but that doesn't seem to be a good reason.
!! guarantees that the result will end up as a 1 or a 0, rather than just the value of _Expression or 0. In C, it's unlikely to matter, but in C++ I think it turns the result of the expression into a bool type, which might be useful in some cases. If you did have some API that required a literal 1 or 0 be passed to it, using !! would be a way to make it happen.
It's possible that you might want an int variable that's either 1 or 0.
So you can't for example pass a 5, instead the double negation would turn that 5 into a 1.
Also, have a look at how TRUE is defined:
#ifndef TRUE
#define TRUE 1
#endif
Therefore, an expression like:
int x = 5;
if ( x == TRUE )
{
//....
}
would not pass, whereas
if ( x )
{
//....
}
would.
Its use is to make sure the value is either 0 or 1. I think it's superfluous with C++'s bool type.
Related
Recently when writing code I encountered a problem. The code was something like this-
if ((var >= min) && (var <= max))
{
return true;
}
Both min and max are macros already defined previously and var is an unsigned integer. I changed the value of min to 0, which generated a warning, unsigned integer >= 0 will always be true.
First I thought to directly remove the first condition to take care of the warning, but my senior refused to do that, as the code is used in not only the project I am working but also other projects, so maybe the value of min may be above 0 in other projects. He suggested me to it like this-
#define min (0-0)
This solved the problem, no warning generated. But I did not understand why did it work? I asked my senior to explain but he said to find out on my own. I searched on google but did not find anything remotely familiar to it.
So can anyone explain to me what happened above?
Thank you in advance.
Answer: Because it seems the compiler doesn`t check the result of expressions.
Just to know: This is a problem. The compiler is correct - unsigned int can not be less than 0. Whatever you pass to this function, that comparison will always be true.
Because you are on work, do what the others tell you, but keep in mind - you are right, that should be removed, because it makes no sense in your current implementation.
Var has to be changed to long long and then everything will be fine! The problem is there!
It is a matter of time, someone to pass negative value to that function and will fail hard. It will make a warning for passing signed value to a function expecting unsigned and the guy will deprecate it to not have warnings ...
#define min (0-0) and #define min (0) would be equivalent for type and value point of view.
It seems that it allows to break the check of your compiler.
Real fix to remove the warning is to handle the case, for example:
if constexpr (min == 0 && std::is_unsigned_v<std::decay_t<decltype(var)>>) {
if (var <= max)
{
return true;
}
} else {
if (var >= min && var <= max)
{
return true;
}
}
which is probably too verbose (and even worse if you do similar stuff for max).
That cure seems not better than the warning :-/
Possible workaround would be to wrap the test in a function,
as I don't think, currently, compilers warn about function returning always true in condition.
so:
// indirect comparison to avoid warning about always true comparison
if (std::less_equal<>{}(min, var) && std::less_equal<>{}(var, max))
{
return true;
}
A macro applies a search and replace before compiling:
So for #define min (0) the code for the compiler will be:
if ((var >= (0)) && (var <= max))
{
return true;
}
And for #define min (0-0) it will be:
if ((var >= (0-0)) && (var <= max))
{
return true;
}
Both var >= 0 and var >= 0-0 are equivalent regarding the types involved in the comparsion.
clang will for example correctly report both with the warning warning: result of comparison of unsigned expression >= 0 is always true [-Wtautological-unsigned-zero-compare].
gcc reports only the (0) case.
Using 0-0 is a bad idea, not only because silencing a warning instead of solving it is a bad idea, but also because that hack might fail in future compiler versions. It just does not solve the problem, but just tricks the compiler. And using macros to define constant also a bad idea.
By usning a constexpr for the constant instead of a macro the case of a >= 0 could have been correctly solved.
Removing var >= min is not necessarily a good idea if the "constant" min exists, as someone could change its value the future. var >= min can only be safely removed the code should not rely on min and should never have a lower bound that is different to the one given by the type of val. So if min has any relevance then the code should be changed to handle the case when it is 0 correctly, so that the compiler is aware that you know that this case could exist.
The #define is a red herring. It only affects situations where min is followed by parentheses, like int x = min (5, 7). It's not a good idea to have a variable with the same name as a macro, but it doesn't hurt you.
Whoever suggested changing the min macro is frankly an idiot. It will fatally break every bit of code that uses the min macro. If you tried that where I work we would have to discuss your further employment, that's how bad it is.
Your problem is that indeed if x is an unsigned variable and min = 0 the comparison x >= 0 will always be true. The compiler gives a warning which in your situation is stupid. A correct change instead if removing the condition would be (x == 0 || x > 0) instead of x >= 0; this will most likely remove the warning.
This question already has answers here:
Double Negation in C++
(14 answers)
double negation in C : is it guaranteed to return 0/1?
(2 answers)
Closed 5 years ago.
I came across this piece of code from the Microsoft implementation of GSL (the C++ Guideline Support Library):
#if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define GSL_LIKELY(x) (!!(x))
#define GSL_UNLIKELY(x) (!!(x))
#endif
I read about the __builtin_expect (here and here), but it is still unclear to me what is the purpose of the double boolean negation operator in (!!(x)). Why is it used?
The file in question is this one.
__builtin_expect works with strict equality, so the point of double negation here is to make sure all truthy values are converted to 1 (and thus match the 1 in GSL_LIKELY), and all the falsy values match the 0 in GSL_UNLIKELY.
The double negation is kept even if __builtin_expect is not available to keep uniformity (as the caller may store the return value for other uses besides as a condition in an if).
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
Currently checking out C++ using this tutorial. It explains what the ! NOT operator is, kind of, but I don't think I fully understand why I'd ever want to use it. Can someone please explain?
The ! operator is useful if you want to check that a condition is not currently satisfied.
Imagine a function that tells you if a particular subsystem of your application was initialized and another function to initialize it:
bool subsystem_is_initialized();
void subsystem_initialize();
You could check that it was initialized and initialize it if it wasn't using the not operator.
if (!subsystem_is_initialized())
subsystem_initialize();
For all practical purposes, it's a shorter way to compare a value to zero, with an explicit suggestion that the affected value is boolean. You don't absolutely need it, but then again, neither do you need multiplications (you can loop over an addition), additions (you can do it with binary logic), or most of binary logic (you can do pretty much anything with NANDs, I've been told, but I haven't researched it myself).
Also keep in mind that, like almost all other C++ operators, it can be overloaded by classes.
A language is not always (in fact as good as never) defined to have the minimal set of features but a set of features that useful. For example, if you had the following code:
if (!test_something())
do_something();
You could also express this as
if (test_something()) {
} else
do_something();
but it would be less easy to read. So, while logical negation can usually be expressed by other constructs of the C++ language, it helps readability to express negation explicitly to indicate your intent.
It's used when you need to flip a true/false in a condition, to increase readability.
e.g.
Compare
// Ensure that the thing is NOT red.
if (thing_is_red() == false)
...
if (!thing_is_red())
...
Okay, you want to divide the sum of two numbers to a third one, so you can do this if the third number is not zero.
#include <iostream>
using namespace std;
int main()
{
int a,b,c,sum;
cin >> a >> b >> c;
sum = a+b;
if (c!=0) //which is equivalent to if(!c)
cout << sum/c;
}
I used an easy example in order to understand it quickly. Is everything okay now? Regards and good luck with your study.
! or the NOT operator is the logical equivalent of a NOT gate.
So, a NOT gate truth table says if x is true, then !x is false. and vice-versa.
Not too difficult if you think of it logically. For example NOT of male is a female, NOT true is false, NOT simple is complex..
The most frequent case is probably with an std::istream:
int i;
std::cin >> i;
if ( ! std::cin ) {
// Something went wrong...
}
Other than that, all sorts of classes have isValid() or
isDone() functions; to iterate using a GoF iterator, for
example:
for ( IteratorType i( init ); ! i.isDone(); i.next() ) {
// Do something with i.element()
}
Map classes often have a contains function, so you might ask
if ( ! myMap.contains( key ) )
You'll also use boolean variables from time to time: for
a linear search where the match condition requires some
complicated evaluation, for example:
bool found = false;
int current = 0;
while ( ! found && current != end ) {
// maybe set found...
}
The tutorial you mention:
NOT: The NOT operator accepts one input. If that input is TRUE, it returns FALSE, and if that input is FALSE, it returns TRUE.
it means NOT operator is unary operator means single operand(not a binary operator)
like && and||` are binary operators and there syntax is:
result = operand1 && operand2
result = operand1 || operand2
Unary is:
result = !operand1
and its result values is revert of operand value id operand1 = True then result would be False and if operand1 = False result is True.
same is written there:
For example, NOT (1) evaluates to 0, and NOT (0) evaluates to 1. NOT (any number but zero) evaluates to 0. In C and C++ NOT is written as !. NOT is evaluated prior to both AND and OR.
in c/c++ 0 is False and
Non 0 is equivalent to True.
there is couple of good examples too!
(1).
!( 1 || 0 )
We know 1 || 0 is 1 means true and application of NOT operator makes it 0 means False:
!( 1 || 0 )
=> ! (1)
=> 0 that is false
Do you notice in this expression we have two operators logical || or and ! NOT operator.
!( 1 || 0 )
^ ^
NOT OR
and notice for OR operator || there is two operands bit single for unary NOT
! operator is used for negation purpose in bool condition checks. There are many places you can use it. Simple example:
if (!existInArray(A, i))
check if i is NOT exist in array.
The point of the ! operator is to make an expression that is false into a true expression. It is most often used as a replacement for == false or == 0. It often makes the expression easier to read:
if (p == NULL || p->next != NULL)
is the same as :
if (!p || p->next)
[Ok, so "easier to read" here is obviously quite subjective].
You have quite a number of answers explaining the NOT operator.
I am not a big fan of the ! operator myself. It is not nearly as visible as it should be (in that, it reverses the meaning of the clause).
For example, despite several years of programming in C++, it still takes me several seconds to parse if ( ! ptr ) as opposed to if ( ptr == NULL ) which instantly conveys me its meaning.
Does if ( ! (i % 2) ) check for even or odd numbers? If you didn't have the answer after your eyes went past the '?', and/or had to review the if condition again, you have just made my case.
Reviewing posts, I agree with some of the posters that the NOT operator has valid uses when applied to bools and function calls. Using ! while processing streams is considered idiomatic.
That said, nearly every programmer I know has been bitten by strcmp. I worked in a shop that has a few #defines such as #define STRCMP_EQUAL 0 etc., and required the check to be written as if ( STRCMP_EQUAL == strcmp(str1, str2) ) which, in my opinion, is orders of magnitude more explicit than if ( ! strcmp(str1, str2) ).
! operator could be used with user defined datatypes(classes and structs in c++).
like every operator(expect . : and ::) !operator could be overloaded. See the following scenario.
//A is empty if memeber size is 0, and no further operations are allowed on other members if
// class is empty.
class A{
int size;
int lot;
int price;
public:
bool operator!()
{
if(lot)
return true;
else
return false;
}
};
A AObj;
//Aobj has size greater than 0
if(!Aobj)
{
//code to Fill or reuse the object.
}
The point of the ! operator is to make an expression that is false into a true expression. It is most often used as a replacement for == false or == 0. It often makes the expression easier to read:
if (p == NULL || p->next != NULL)
is the same as :
if (!p || p->next)
[Ok, so "easier to read" here is obviously quite subjective].
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Double Negation in C++ code
When I scanned the Webkit source code, I found a strange use of the boolean "not" operator !:
BOOL enabled;
if (SUCCEEDED(sharedPreferences->continuousSpellCheckingEnabled(&enabled)))
continuousSpellCheckingEnabled = !!enabled;
if (SUCCEEDED(sharedPreferences->grammarCheckingEnabled(&enabled)))
grammarCheckingEnabled = !!enabled;
Why don't they use enabled directly instead of !!enabled?
It's a C++ trick to convert anything to 1 or 0.
For example, 42 is logically true, but is not 1, so applying !! to it, you turn it into 1.
It's meant to force a value to a boolean. So if the value is evaluating to something, you'll get true.
It forces a true value to be exactly 1.
In a boolean context (if (x), while (x), x ? a : b, for (; x; )), a value which is 0 means false, while any other value means true.
If your function accepts a truth value, but you need exactly 1 there, !! is fine.
In other words, !!x is the same as x ? 1 : 0.
Most probably continuousSpellCheckingEnabled is of type bool. BOOL is defined as int, so:
continuousSpellCheckingEnabled = enabled;
issues a warning, while:
continuousSpellCheckingEnabled = !!enabled;
does not.
why don't they directly use "enabled"
Double negation only cancels out for boolean values (0 and 1) so !!(0) == 0 for non-boolean values the value will be converted to boolean !!(100) == 1
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to check for equals? (0 == i) or (i == 0)
Why does one often see “null != variable” instead of “variable != null” in C#?
Why do some experienced programmers write expressions this way?
What is the meaning of NULL != value in C++?
For example,
int k =5;
if( 5 == k )
{
}
is preferred over
if (k == 5)
{
}
Is it considered only for formatting purpose or is there any reason behind it?
Because that form makes it harder to introduce a bug by forgetting one of the equals signs. Imagine if you did this:
if (k = 5)
This was intended as a comparison, but it's now an assignment! What's worse, it is legal, and it will mess up your program in multiple ways (the value of k is changed, and the conditional always evaluates to true).
Contrast this with
if (5 = k)
This is not legal (you cannot assign to a literal) so the compiler will immediately flag it as an error.
That said, this style of writing code (assignments within conditionals) is not as prevalent today as it once was. Most modern compilers will flag this as a warning, so it's unlikely to go undetected. Personally I don't like the second form and since the compiler is there to help I don't use it.
If you mistype and write
if (k = 5) // instead of ==
then you likely just introduced a hard to find bug. (Actually, it used to be hard to find. Nowadays, most compilers will flag this as a warning.)
This, however, will result in a compile-time error
if (5 = k)
BTW, this style is called Yoda Conditions :-)
It's to avoid the mistake of
if( k = 5 ) {
}
which would always equal true.
A. Who said it's preferred ?!
the only reason i can think of it's to avoid:
int k =5;
if( 5 = k )//notice one "="
{
}
like this you will get a compilation error, while the other way will work. but I think it's less readable and less preferred.
First of all, most people prefer the second form, since it feels "more natural"; the first form is felt as "reversed", and in fact is often called "Yoda conditional".
The rationale behind using the first form is to avoid accidental assignment when typing = instead of == by error. Since in a conditional you can write any expression, = is allowed, so in case of mistyping the instruction
if(k = 5)
{
}
won't check if k is equal to 5, but will assign 5 to k and, since = returns a reference to its left hand operator, the condition will be evaluated as true and the if body will always be executed.
On the other hand, if you typed = instead of == in the Yoda conditional you would get
if(5 = k)
{
}
which results in a compilation error, since you can't assign anything to a literal (5).
Although they look like a good idea, "Yoda conditionals" are quite weird looking, and, most importantly, almost any good compiler with warnings turned on will warn you anyway if you write an assignment inside a conditional expression, so most people just use the "natural looking" form.
It's because a common typo is typing = instead of ==.