Disadvantages of using "variable !== FALSE" [closed] - c#

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 10 years ago.
Reading a job ad, a requirement (sigh) was that the applicant should more or less hate the usage of variable !== FALSE. I, however, cannot see the reason of this, since I find it quite handy.
Say that a function (get_user( int user_id )) returns FALSE if it doesn't succeed (find the requested user), I can simply use:
user = get_user(823);
if(user !== FALSE) {
// User found
} else {
// No user found
}
I could, of course, simply use if(!user), however, I don't always find it suiting, especially when I have a few conditions to meet.
Are there any disadventages of writing code like this?
Clarification: This is a more global question, as the ad were against PHP usage of !== FALSE and C# usage of != FALSE.

You say get_user returns false when it doesn't succeed - and that's most of the problem. If a function call does not succeed, it should throw an exception, not return an answer that is not type safe ("false" as opposed to a User).

You could do on accident
if($variable = FALSE)
And this would change the value of $variable

In Javascript, the two following are equivalents:
user != FALSE
!user
However, this is slightly different:
user !== FALSE
as it is the negation of ===, which checks for both values and types to be the same.
Reference:
http://www.w3schools.com/js/js_comparisons.asp

If you have in Java
Boolean flag1 = new Boolean(true);
Boolean flag2 = new Boolean(false);
if (flag1 == Boolean.TRUE || flag1 == Boolean.FALSE) // is false.
if (flag2 == Boolean.TRUE || flag2 == Boolean.FALSE) // is false.
if (flag1 != Boolean.FALSE && flag2 != Boolean.FALSE) // is true
Using == FALSE or != FALSE may not work the way you think so while it is more verbose, it is also error prone.

From a dev point of view, it's better to design your methods that do not return different values that evaluate to FALSE. Eg your function should not return multiple possible values of 0 or NULL or FALSE or "" (empty string) or empty array() because this would require some unobvious logic to check the result after.
If we talk about PHP on the other hand it's good to know that some functions return both zero or false, eg strpos. You should not assume if (!strpos(...)) means the string is not contained in the other string, it could be on zero position, which evaluates to FALSE. Sometimes also a function might return FALSE on failure or empty array on success (that did not produce result that evaluates to TRUE).
So, point out there are cases this is neccessary or useful, but in general its bad practice to return multiple values that evaluate to FALSE, thus requiring to include the type in the comparisment operator.

What is asked for a requirement might be related to taste and to field of use.
In a strict logical system, one might be inclined to select ID values that represent objects (in any kind of store or memory) to not be 0 (and to be positive numbers only).
That leaves room for having 0 to represent a non-existing object (so called NULL object).
Also negative numbers could be used to signal meta information like errors. But a strict system should not use any negative numbers and pass meta-information on some context instead of the mainline of data-flow.
Probably this is what is wanted. In that case the value FALSE would not exist, because the whole system is about numbers only.
The benefit of such a system is that it works nearly in every programming language and across different paradigms.
Also commonly the number zero expresses a falsy condition, and non-zero numbers a truthy one.

Actually it depends on the language.
C
In the programm language C there is no bool and then TRUE or FALSE are defined values, mostly 1 for TRUE and 0 for FALSE. However, since this is just a sort of convention, some define FALSE as -1 and TRUE as 255. You see this results in strange behavior, therefor in C always check against a defined value and make sure those values match.
Also in C some people think the best way is to use 'FALSE == a' instead of 'a == FALSE'. The reason is that if one = is forgotten, the first (FALSE == a) gives a compilation error, and the second is treated as an assignment, which clearly is unintended.
C#
However, in C#, true and false are predefined and checking a variable against true and false is quite useless. a == true means exactly the same as just writing a.
Python
In Python however, there is a change. a == true means that the variable a should be a boolean, if you write just 'a' then it means it can also be 0, [], {} or any inited value.
A bit off-topic: I think if such detail is part of a 'requirement for a job', the job requirements would be like 10,000 pages.

Related

Unit Test: CollectionAssert.AllItemsAreNotNull [duplicate]

This question already has answers here:
Why does IQueryable.All() return true on an empty collection?
(11 answers)
Closed 7 years ago.
var strs = new Collection<string>();
bool b = strs.All(str => str == "ABC");
The code creates an empty collection of string, then tries to determine if all the elements in the collection are "ABC".
If you run it, b will be true.
But the collection does not even have any elements in it, let alone any elements that equal to "ABC".
Is this a bug, or is there a reasonable explanation?
It's certainly not a bug. It's behaving exactly as documented:
true if every element of the source sequence passes the test in the specified predicate, or if the sequence is empty; otherwise, false.
Now you can argue about whether or not it should work that way (it seems fine to me; every element of the sequence conforms to the predicate) but the very first thing to check before you ask whether something is a bug, is the documentation. (It's the first thing to check as soon as a method behaves in a way other than what you expected.)
All requires the predicate to be true for all elements of the sequence. This is explicitly stated in the documentation. It's also the only thing that makes sense if you think of All as being like a logical "and" between the predicate's results for each element. The true you're getting out for the empty sequence is the identity element of the "and" operation. Likewise, the false you get from Any for the empty sequence is the identity for logical "or".
If you think of All as "there are no elements in the sequence that are not", this might make more sense.
It is true, as nothing (no condition) makes it false.
The docs probably explain it. (Jon Skeet also mentioned something a few years back)
Same goes for Any (the opposite of All) returning false for empty sets.
Edit:
You can imagine All to be implemented semantically the same as:
foreach (var e in elems)
{
if (!cond(e))
return false;
}
return true; // no escape from loop
Most answers here seem to go along the lines of "because that's how is defined". But there is also a logical reason why is defined this way.
When defining a function, you want your function to be as general as possible, such that it can be applied to the largest possible number of cases. Say, for instance, that I want to define the Sum function, which returns the sum of all the numbers in a list. What should it return when the list is empty? If you'd return an arbitrary number x, you'd define the function as the:
Function that returns the sum of all numbers in the given list, or x if the list is empty.
But if x is zero, you can also define it as the
Function that returns x plus the given numbers.
Note that definition 2 implies definition 1, but 1 does not imply 2 when x is not zero, which by itself is enough reason to pick 2 over 1. But also note 2 is more elegant and, in its own right, more general than 1. Is like placing a spotlight farther away so that it lightens a larger area. A lot larger actually. I'm not a mathematician myself but I'm sure they'll find a ton of connections between definition 2 and other mathematical concepts, but not so many related to definition 1 when x is not zero.
In general, you can, and most likely want to return the identity element (the one that leaves the other operand unchanged) whenever you have a function that applies a binary operator over a set of elements and the set is empty. This is the same reason a Product function will return 1 when the list is empty (note that you could just replace "x plus" with "one times" in definition 2). And is the same reason All (which can be thought of as the repeated application of the logical AND operator) will return true when the list is empty (p && true is equivalent to p), and the same reason Any (the OR operator) will return false.
The method cycles through all elements until it finds one that does not satisfy the condition, or finds none that fail. If none fail, true is returned.
So, if there are no elements, true is returned (since there were none that failed)
Here is an extension that can do what OP wanted to do:
static bool All<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool mustExist)
{
foreach (var e in source)
{
if (!predicate(e))
return false;
mustExist = false;
}
return !mustExist;
}
...and as others have pointed out already this is not a bug but well-documented intended behavior.
An alternative solution if one does not wish to write a new extension is:
strs.DefaultIfEmpty().All(str => str == "ABC");
PS: The above does not work if looking for the default value itself!
(Which for strings would be null.)
In such cases it becomes less elegant with something similar to:
strs.DefaultIfEmpty(string.Empty).All(str => str == null);
If you can enumerate more than once the easiest solution is:
strs.All(predicate) && strs.Any();
i.e simply add a check after that there actually were any element.
Keeping the implementation aside. Does it really matter if it is true? See if you have some code which iterates over the enumerable and executes some code. if All() is true then that code is still not going to run since the enumerable doesn't have any elements in it.
var hungryDogs = Enumerable.Empty<Dog>();
bool allAreHungry = hungryDogs.All(d=>d.Hungry);
if (allAreHungry)
foreach (Dog dog in hungryDogs)
dog.Feed(biscuits); <--- this line will not run anyway.

whats the meaning of this sytax in VB "If(a & b)" [duplicate]

This question already has answers here:
Equivalent of Visual Basic's And and Or in C#?
(6 answers)
Closed 7 years ago.
I'm trying to translate a certain code to c#.
Basically I understand most of the code I'm dealing with, and even the intent of the original code.
but I wanna be sure I have all my bases covered.
its the 5th post in this topic: http://www.pcreview.co.uk/threads/how-to-use-getwindowlong-properly-in-vb-net.1312789/
by user Kresimir
the code at question:
Dim ret As Integer = User32DLL.GetWindowLong(Me.Handle, -16)
Dim s As String = String.Empty
If (ret And WS_BORDER) Then s &= "WS_BORDER" & NewLine
I do not understand what the "If (ret And WS_BORDER)" statement is supposed to do, and how to translate it to C#
is it:
if (ret!=null & WS_BORDER!=null)
or something else?
Thank you.
edit: note. If I use the above mentioned C# statement, VS gives me a notice that "the result of the expression is always false since a value of type "int" is never equal to "null" of type "int?"
^I guess I can neglect it(googling it as we speak), but if sm1 wishes to give me a "free of charge explanation" I'd appreciate it :*
ps. I'm really a newb to this, so I'm sorry if I overlooked something obvious.
None of the previous answers are right:
if((ret & WS_BORDER) != 0)
This is a check to see if a variable contains a flag, in this case WS_BORDER.
This is a bitwise logic operation. When Visual Basic converts numeric data type values to Boolean, 0 becomes False and all other values become True. So if the statement is not 0:
User32DLL.GetWindowLong(Me.Handle, -16)
...and WS_BORDER is not falsy the result will be true. If either are false, the result will be false.

Nullable Types and Operators

I was reading about Nullable Types and Operators from Wrox and came across the following statement:
When comparing nullable types, if only one of the operands is null, the comparison will always equate to false. This means that you cannot assume a condition is true just because its opposite is false.
Now, I get what the first statement means but didn't get the second statement.
Could you please elaborate?
It appears like the quote is saying that any comparison at all with a null type will return null, regardless of the operand.
So something like (null != 5) Would return false, where (null == 5) would also return false.
Now, the funny thing is, that when I ran a program, null != 5 returned true, so while I can't verify that statement for c# 2.0, it's definitely not true anymore in c# 4.0 +
This is the sample code I've used:
int? a = null;
int? b = 5;
if (a != b)
{
Console.WriteLine("A != B");
}
if (a == b)
{
Console.WriteLine("A == B");
}
This is the output
A != B
Press any key to continue . . .
That quote is wrong, MSDN is the official source: http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx
When you perform comparisons with nullable types, if the value of one
of the nullable types is null and the other is not, all comparisons
evaluate to false except for != (not equal).
The second statement simply means that a comparison and its opposite may be both false, eg a>=b and a<b are both false.
Here's the logic. Null kind of means an unknown value. Now try to calculate 5<null, 5<=null, 5==null, 5>=null, 5>null. You can't exactly calculate any of these, they are not true or false either, they are unknown, but false makes a bit more sense than true. The exception is 5!=null. An exact number is not unknown, so it makes a bit more sense that it's true than false. So == and != are the opposite of each other, it's the easy case, but you can't say that for greater-less comparisons. It was a design choice when they made C#/.NET.
SQL on the other hand got it quite right I think with 3-valued-logic, see here: http://en.wikipedia.org/wiki/Null_%28SQL%29#Comparisons_with_NULL_and_the_three-valued_logic_.283VL.29

Why is there a difference in checking null against a value in VB.NET and C#?

In VB.NET this happens:
Dim x As System.Nullable(Of Decimal) = Nothing
Dim y As System.Nullable(Of Decimal) = Nothing
y = 5
If x <> y Then
Console.WriteLine("true")
Else
Console.WriteLine("false") '' <-- I got this. Why?
End If
But in C# this happens:
decimal? x = default(decimal?);
decimal? y = default(decimal?);
y = 5;
if (x != y)
{
Debug.WriteLine("true"); // <-- I got this -- I'm with you, C# :)
}
else
{
Debug.WriteLine("false");
}
Why is there a difference?
VB.NET and C#.NET are different languages, built by different teams who have made different assumptions about usage; in this case the semantics of a NULL comparison.
My personal preference is for the VB.NET semantics, which in essence gives NULL the semantics "I don't know yet". Then the comparison of 5 to "I don't know yet". is naturally "I don't know yet"; ie NULL. This has the additional advantage of mirroring the behaviour of NULL in (most if not all) SQL databases. This is also a more standard (than C#'s) interpretation of three-valued logic, as explained here.
The C# team made different assumptions about what NULL means, resulting in the behaviour difference you show. Eric Lippert wrote a blog about the meaning of NULL in C#. Per Eric Lippert: "I also wrote about the semantics of nulls in VB / VBScript and JScript here and here".
In any environment in which NULL values are possible, it is imprtant to recognize that the Law of the Excluded Middle (ie that A or ~A is tautologically true) no longer can be relied on.
Update:
A bool (as opposed to a bool?) can only take the values TRUE and FALSE. However a language implementation of NULL must decide on how NULL propagates through expressions. In VB the expressions 5=null and 5<>null BOTH return false. In C#, of the comparable expressions 5==null and 5!=null only the second first [updated 2014-03-02 - PG] returns false. However, in ANY environment that supports null, it is incumbent on the programmer to know the truth tables and null-propagation used by that language.
Update
Eric Lippert's blog articles (mentioned in his comments below) on semantics are now at:
Sep. 30, 2003 - A Whole Lot of Nothing
Oct. 1, 2003 - A Little More on Nothing
Because x <> y returns Nothing instead of true. It is simply not defined since x is not defined. (similar to SQL null).
Note: VB.NET Nothing <> C# null.
You also have to compare the value of a Nullable(Of Decimal) only if it has a value.
So the VB.NET above compares similar to this(which looks less incorrect):
If x.HasValue AndAlso y.HasValue AndAlso x <> y Then
Console.WriteLine("true")
Else
Console.WriteLine("false")
End If
The VB.NET language specification:
7.1.1 Nullable Value Types
... A nullable value type can contain the same values as the non-nullable
version of the type as well as the null value. Thus, for a nullable
value type, assigning Nothing to a variable of the type sets the value
of the variable to the null value, not the zero value of the value
type.
For example:
Dim x As Integer = Nothing
Dim y As Integer? = Nothing
Console.WriteLine(x) ' Prints zero '
Console.WriteLine(y) ' Prints nothing (because the value of y is the null value) '
Look at the generated CIL (I've converted both to C#):
C#:
private static void Main(string[] args)
{
decimal? x = null;
decimal? y = null;
y = 5M;
decimal? CS$0$0000 = x;
decimal? CS$0$0001 = y;
if ((CS$0$0000.GetValueOrDefault() != CS$0$0001.GetValueOrDefault()) ||
(CS$0$0000.HasValue != CS$0$0001.HasValue))
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false");
}
}
Visual Basic:
[STAThread]
public static void Main()
{
decimal? x = null;
decimal? y = null;
y = 5M;
bool? VB$LW$t_struct$S3 = new bool?(decimal.Compare(x.GetValueOrDefault(), y.GetValueOrDefault()) != 0);
bool? VB$LW$t_struct$S1 = (x.HasValue & y.HasValue) ? VB$LW$t_struct$S3 : null;
if (VB$LW$t_struct$S1.GetValueOrDefault())
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false");
}
}
You'll see that the comparison in Visual Basic returns Nullable<bool> (not bool, false or true!). And undefined converted to bool is false.
Nothing compared to whatever is always Nothing, not false in Visual Basic (it is the same as in SQL).
The problem that's observed here is a special case of a more general problem, which is that the number of different definitions of equality that may be useful in at least some circumstances exceeds the number of commonly-available means to express them. This problem is in some cases made worse by an unfortunate belief that it is confusing to have different means of testing equality yield different results, and such confusion might be avoided by having the different forms of equality yield the same results whenever possible.
In reality, the fundamental cause of confusion is a misguided belief that the different forms of equality and inequality testing should be expected to yield the same result, notwithstanding the fact that different semantics are useful in different circumstances. For example, from an arithmetic standpoint, it's useful to be able to have Decimal which differ only in the number of trailing zeroes compare as equal. Likewise for double values like positive zero and negative zero. On the other hand, from a caching or interning standpoint, such semantics can be deadly. Suppose, for example, one had a Dictionary<Decimal, String> such that myDict[someDecimal] should equal someDecimal.ToString(). Such an object would seem reasonable if one had many Decimal values that one wanted to convert to string and expected there to be many duplicates. Unfortunately, if used such caching to convert 12.3 m and 12.40 m, followed by 12.30 m and 12.4 m, the latter values would yield "12.3", and "12.40" instead of "12.30" and "12.4".
Returning to the matter at hand, there is more than one sensible way of comparing nullable objects for equality. C# takes the standpoint that its == operator should mirror the behavior of Equals. VB.NET takes the standpoint that its behavior should mirror that of some other languages, since anyone who wants the Equals behavior could use Equals. In some sense, the right solution would be to have a three-way "if" construct, and require that if the conditional expression returns a three-valued result, code must specify what should happen in the null case. Since that is not an option with languages as they are, the next best alternative is to simply learn how different languages work and recognize that they are not the same.
Incidentally, Visual Basic's "Is" operator, which is lacking in C, can be used to test for whether a nullable object is, in fact, null. While one might reasonably question whether an if test should accept a Boolean?, having the normal comparison operators return Boolean? rather than Boolean when invoked on nullable types is a useful feature. Incidentally, in VB.NET, if one attempts to use the equality operator rather than Is, one will get a warning that the result of the comparison will always be Nothing, and one should use Is if one wants to test if something is null.
May be
this
post well help you:
If I remember correctly, 'Nothing' in VB means "the default value". For a value type, that's the default value, for a reference type, that would be null. Thus, assigning nothing to a struct, is no problem at all.
This is a definite weirdness of VB.
In VB, if you want to compare two nullable types, you should use Nullable.Equals().
In your example, it should be:
Dim x As System.Nullable(Of Decimal) = Nothing
Dim y As System.Nullable(Of Decimal) = Nothing
y = 5
If Not Nullable.Equals(x, y) Then
Console.WriteLine("true")
Else
Console.WriteLine("false")
End If
Your VB code is simply incorrect - if you change the "x <> y" to "x = y" you will still have "false" as the result. The most common way of expression this for nullable instances is "Not x.Equals(y)", and this will yield the same behavior as "x != y" in C#.

Is (--i == i++) an Undefined Behavior?

this question is related to my previous problem. The answer I got was "It is an Undefined behavior."
Please anyone explain:
What is an undefined behavior?
how can I know my code has an undefined behavior?
Example code:
int i = 5;
if (--i == i++)
Console.WriteLine("equal and i=" + i);
else
Console.WriteLine("not equal and i=" + i);
//output: equal and i=6
What is an Undefined-Behaviour?
It's quite simply any behaviour that is not specifically defined by the appropriate language specification. Some specs will list certain things as explicitly undefined, but really anything that's not described as being defined is undefined.
how can I know my code has an undefined behavior?
Hopefully your compiler will warn you - if that's not the case, you need to read the language specification and learn about all the funny corner cases and nooks & crannies that cause these sorts of problems.
Be careful out there!
It's undefined in C, but well-defined in C#:
From C# (ECMA-334) specification "Operator precedence and associativity" section (§14.2.1):
Except for the assignment operators and the null coalescing operator, all
binary operators are left-
associative, meaning that operations
are performed from left to right.
[Example: x + y + z is evaluated as (x + y) + z. end example]
So --i is evaluated first, changing i to 4 and evaluating to 4. Then i++ is evaluating, changing i to 5, but evaluating to 4.
Yes, that expression is undefined behavior as well (in C and C++). See http://en.wikipedia.org/wiki/Sequence_point for some information on the rules; you can also search for "sequence point" more generally (that is the set of rules that your code violates).
(This assumes C or C++.)
Carl's answer is exact in general.
In specific, the problem is what Jeremiah pointed out: sequence points.
To clarify, the chunk of code (--i == ++i) is a single "happening". It's a chunk of code that's evaluated all at once. There is no defined order of what happens first. The left side could be evaluated first, or the right side could, or maybe the equality is compared, then i is incremented, then decremented. Each of these behaviors could cause this expression to have different results. It's "undefined" what will happen here. You don't know what the answer will be.
Compare this to the statement i = i+1; Here, the right side is always evaluated first, then its result is stored into i. This is well-defined. There's no ambiguity.
Hope that helps a little.
In C the result is undefined, in C# it's defined.
In C, the comparison is interpreted as:
Do all of these, in any order:
- Decrease i, then get value of i into x
- Get value of i into y, then increase i
Then compare x and y.
In C# there are more operation boundaries, so the comparison is interpreted as:
Decrease i
then get value of i into x
then get value of i into y
then increase i
then compare x and y.
It's up to the compiler to choose in which order the operations are done within an operation boundary, so putting contradictory operations within the same boundary causes the result to be undefined.
Because the C standard states so. And your example clearly shows an undefined behabiour.
Depending on the order of evaluation, the comparison should be 4 == 5 or 5 == 6. And yet the condition returns True.
Your previous question was tagged [C], so I'm answering based on C, even though the code in your current question doesn't look like C.
The definition of undefined behavior in C99 says (§3.4.3):
1 undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
for which this International Standard imposes no requirements
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
Appendix J.2 of the C standard has a (long -- several pages) list of undefined behavior, though even that still isn't exhaustive. For the most part, undefined behavior means you broke the rules, so the way to know it is to know the rules.
Undefined behavior == the result cannot be guaranteed to always be the same whenever you run it in the exact same conditions, or the result cannot be guaranteed to always be the same whenever you use different compilers or runtimes to execute it.
In your code, since it is using a equal comparison operator which does not specify which side of the operands should be executed first, --i or i++ may end up running first, and your answer will depend on the actual implementation of the compiler. If --i is executed first, it will be 4 == 4, i=5; if i++ is implemented first, it will be 5 == 5, i=5.
The fact that the answer may turn out to be the same does not prevent the compiler from warning you that this is an undefined operation.
Now if this is a language that defines that the left hand side (or right hand side) should always be executed first, then the behavior will no longer be undefined.

Categories