|
I was talking hypothetically, i.e. if '=' was the identity equality operator; expressions like the one I used wouldn't work.
while((line == reader.ReadLine()) != null) { }
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb]
Jonathan C Dickinson (C# Software Engineer)
|
|
|
|
|
Jonathan C Dickinson wrote: if '=' was the identity equality operator; expressions like the one I used wouldn't work.
I don't see that that follows, since the compiler would still recognise != as the not equals operator.
It's time for a new signature.
|
|
|
|
|
Hurm... The example doesn't need a == operator because it is demonstrating what is possible when a = and a == are distinct. With == around; = becomes more versatile. Because = is more versatile the example I gave is possible.
If there was only = (and no == ) the example I gave simply wouldn't work (you would get an warning saying that a boolean is never null). I think the mathematical term for this kind of 'proof' is proof by contradiction.
The compiler would recognize != as the not equals operator, BUT it would recognize the = as identity equality and not assignment. Thus the AST would look (where the VB-route is taken) something like this:
WHILESTMT(BOOLEXPR(BOOLEXPR("line", Operator.IdentityEquality, "reader.ReadLine"), Operator.IdentityInequality, NULL))
As opposed to (and why my example works):
WHILESTMT(BOOLEXPR(BOOLEXPR("line", Operator.Assign, "reader.ReadLine"), Operator.IdentityInequality, NULL))
More simply, the following expression results in a boolean type (and boolean value) in VB:
a = b
In C# is results in the type of 'a' (and the value contained by 'a'). Which is why these statements are possible:
int0 = int1 = int2 = int3 = int4 = 0; // Set all to 0.
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb]
Jonathan C Dickinson (C# Software Engineer)
|
|
|
|
|
It's time for a new signature.
|
|
|
|
|
*shrug*
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb]
Jonathan C Dickinson (C# Software Engineer)
|
|
|
|
|
I don't like this way of working personally, I think the semantics are less clear and it always feels like cutting the suit to match the cloth to me. I vaguely remember it was a good idea to use the 2nd form in C++, the compiler wouldn't throw an error otherwise, and would happily set btnPause.Content to "Pause"
I haven't voted (and won't ) vote on your response - I don't think there is anything wrong with what you said, it is just a different opinion about how to work.
ragnaroknrol The Internet is For Porn[^]
Pete o'Hanlon: If it wasn't insulting tools, I'd say you were dumber than a bag of spanners.
|
|
|
|
|
I have to say I tend to use the alternate form somewhat less these days, but it was offered to me years ago as a good way of catching such mistakes, especially in the days before C++ when I was writing pure C.
And as for the down voting, well frankly my dear ... I just wish these jerks would have the guts to add a reasoned and useful argument as the rest of you have done.
It's time for a new signature.
|
|
|
|
|
I used to work in a shop (doing just plain C) that had that specified in the coding standards. It made no sense to me, but I went along. One day I was talking with "the guru" (who probably wrote the standard) and he agreed that it was pointless so he didn't enforce it.
The basic problem is that it only works when comparing an Lvalue and an Rvalue; many times that is not the case, so you need to think about what you are doing and recognize the situation. And if you can do that, then chances are you won't make that mistake anyway.
When it comes right down to it; anyone who is prone to that kind of mistake is also unlikely to remember the rule.
By the way... HP C V7.3-009 on OpenVMS Alpha V8.3 says:
JB> cc aa.c /warn=(enable=(check),verbose)
if ( result = 5 )
....^
%CC-I-CONTROLASSIGN, In this statement, the assignment expression "result=5" is used as the controlling expression of an if, while o
r for statement.
at line number 13 in file MY$ROOT:[000000]AA.C;3
Description: A common user mistake is to accidentally use assignment operator "=" instead of the equality operator "==" in an expres
sion that controls a transfer. For example saying if (a = b) instead of if (a == b). While using the assignment operator is valid,
it is often not what was intended. When this message is enabled, the compiler will detect these cases at compile-time. This can oft
en avoid long debugging sessions needed to find the bug in the user's program.
User Action: Make sure that the assignment operator is what is expected.
if ( 5 = result )
.........^
%CC-E-NEEDLVALUE, In this statement, "5" is not an lvalue, but occurs in a context that requires one.
at line number 18 in file MY$ROOT:[000000]AA.C;3
Description: An expression that must be an lvalue was not an lvalue. For example, the operand of the address-of operator must be an
lvalue.
User Action: Modify the expression so that it is an lvalue.
Edit:
C:\>cc aa
Borland C++ 5.5 for Win32 Copyright (c) 1993, 2000 Borland
aa.c:
Warning W8060 aa.c 14: Possibly incorrect assignment in function main
C:\>\mingw\bin\gcc -Wall aa.c
aa.c: In function `main':
aa.c:14: warning: suggest parentheses around assignment used as truth value
modified on Saturday, August 7, 2010 11:40 PM
|
|
|
|
|
Right.
I've seen some C compilers (don't recall which, I've used so many for all kinds of embedded systems) also warning about the probably mistaken assignment in an if statement.
|
|
|
|
|
I thought I had seen something like that in my days as a UNIX programmmer, it must have been gcc and possibly Sun' own C/C++ compiler.
It's time for a new signature.
|
|
|
|
|
Yeugh! That looks too much like C++ for my liking. The alternate compiler error is just as confusing; and the alternate code is more confusing to read.
The reason they did things the second way in C++ is because:
if (btnPause->Content = "Pause")
And:
if ("Pause" = btnPause->Content)
We don't need to resort to such language hacks in C#. Please, for the kittens!
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb]
Jonathan C Dickinson (C# Software Engineer)
|
|
|
|
|
The point isn't that the compiler gives a more useful message (as has been pointed out), the point is it will give an error message even if the type in question in fact has a conversion-to-bool operator!
Whether or not you cannot figure out what the actual cause of the resulting message is, is an entirely different question. I'd suppose everyone intelligent enough to put literals on the left hand side of a comparison will recognise what it means when the compiler states he wants an lvalue! At least I am
|
|
|
|
|
I agree, but it seems this construct is no longer 'in vogue'. Being a sheep I'll just follow the herd.
It's time for a new signature.
|
|
|
|
|
Hmm, has it ever been 'en vogue'? Judging by my experience, I believe the reason why 'nobody' uses it is that few people know about it, not that it isn't 'en vogue' any more.
Also, it seems more natural to ask 'does x currently have a value of 2?' than 'does 2 happen to be the value currently stored in x?'. So even when I tell people about it, they might be reluctant to change their style accordingly.
|
|
|
|
|
Stefan63 wrote: has it ever been 'en vogue'?
Possibly not, but it was certainly common practice at my last company, which had a fairly large group of developers around the world. I've never actually tried to see if it's in any of the published books on C++ (or C).
It's time for a new signature.
|
|
|
|
|
There's a difference between
if (btnPause.Content = "Pause")
and
if (btnPause.Content == "Pause")
You aren't comparing with btnPause.Content, but assigning to it. The assignment operator returns the assigned object, so in effect your code is like this:
btnPause.Content = "Pause";
if (btnPause)
It's a classic typo-bug, and the safest way of avoiding it is to make a habit of putting the constant (if you have one) to the left:
if ("Pause" = btnPause.Content)
This would give a compiler error along the lines of "Cannot assign to constant", which is more helpful.
|
|
|
|
|
I already suggested this above; you may want to read Harold, Luc and Keith's comments in response. Also note that someone around here really hates this idea and is downvoting us for suggesting it. I've given you a 5 to compensate.
It's time for a new signature.
|
|
|
|
|
Yes, I saw that once I'd replied. It was the changed subject line that threw me off.
Sorry, I'm new in the neighbourhood.
|
|
|
|
|
Cool Cow Orjan wrote: Sorry, I'm new in the neighbourhood.
No problem, we all make mistakes from time to time. And welcome to CodeProject, judging by some of your posts I have seen I am sure your contributions will have a positive impact for many people.
It's time for a new signature.
|
|
|
|
|
Ok, first things first...If this is August 10th, I will gladly eat this post. Why are the messages all dated the 10th? Secondly, being "new in the neighbourhood" sounds like a good reason for everyone to pile on and really "get you" for not plowing through all of the messages!! LOL!
|
|
|
|
|
The messages are dated [date] [month] [year], so they're all posted in 2010, or '10 for short. And it's August 10th now...
As for piling on, I'd expect to be shouted at for factual errors, or bad advice (like saying "Use Emacs" but not so much for being a newbie. And should that happen, well, I've been online long enough to grow a reasonably thick skin.
|
|
|
|
|
Personally, I'd prefer to hide the Pause button and show the resume button rather than repurpose the one button and do string compares.
|
|
|
|
|
Personally when performing value comparisons with strings (and many other types) I find I am far less prone to syntax errors if I make myself use the "Equals" method. With strings in particular, it is a good practice to use the static method
String.Equals(string a, string b) as this eliminates the possibility of a null reference exception.
With this in mind, the boolean in your if statement would look like this:
if (String.Equals(btnPause.Content, "Pause"))
"We are men of action; lies do not become us."
|
|
|
|
|
You can't get a NRE using the == operator. The .Net runtime essentially does this:
if (Object.ReferenceEquals(a, null) && Object.ReferenceEquals(b, null)) return true;
else if (Object.ReferenceEquals(a, null) || Object.ReferenceEquals(b, null)) return false;
else return a.Equals(b);
Unless you override the == operator (in which case you should do this in the header).
The String.Equals is better because you would be more inclined to use the StringComparison enum[^] - but that is only the case for Strings.
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chineese Proverb]
Jonathan C Dickinson (C# Software Engineer)
|
|
|
|
|
Jonathan,
I can see why my language may have been confusing. I was not meaning to imply that using the == operator would result in a NullReferenceException. My first statement was that the "Equals" method should be used to make the comparison, and I then went on to state that the static method should be preferred for strings (rather than the instance method) since using the instance method could result in a NullReferenceException while using the static method will not. Looking back at my post, however, I can see why one might think I was implying something different, which was not my intent. Regardless, thanks.
"We are men of action; lies do not become us."
|
|
|
|