- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Oh, so what's strcmp()? Have you ever coded in C? Or in C++? Yeah - in C++ you can use operator overloading, but that makes things a bit fuzzy, cause how the hell are you gonna compare 2 pointers if you do in an easily readable way? This has nothing to do with "object oriented", this has to do with "how computers work™". It are only the "easy" languages that make string comparison simple. If you don't know anything about how a cpu or computer works, it's more logical, but if you do... well the story becomes a bit different [:)] Comparing a string is simply a more complex operation than telling the cpu to compare 2 things. Most ppl knowing a bit about coding have names for that, like "function", "method", "procedure", ...
I do agree that this isn't C or Java - and I even highly doubt that it's C++... And yes - a lot of reactions here are also WTF's [:D]
Admin
I'm going to assume it was written the correct way, he had a bug that was frustrating him to the point that he'd rewrite the most basic lines of code to make sure they were correct, and after he fixed the bug he didn't bother to change it back.
Admin
This cannot be C, look close at the comments. They are not valid in standard C. (though gcc at least supports them)
Admin
#include <iostream>
struct foo
{
operator bool() { return false; }
};
foo operator&&( const foo& lhs, const foo& rhs )
{
std::cout << ""foo operator&&(const foo&, const foo&)" called\n";
return foo();
}
struct bar
{ };
foo operator!=(const bar& lhs, const char* rhs)
{
std::cout << ""foo operator!=(const bar&, const char*)" called\n";
return foo();
}
int main()
{
bar baz;
if (baz != "operator" &&
baz != "overloading" &&
baz != "fun" &&
baz != "with" &&
baz != "C++")
{
std::cout << "compile & run it, should you think it cannot be an optimization.";
}
}</iostream>
Admin
Actually, it could be C, but it probably wouldn't do what the author expected; Bearing in mind we don't actually know what typec is, then it could possibly be a char* of some sort, in which case the if statements would actually compare the pointers of the two strings [arrays, whatever]. If this was user input of some sort (most likely) then typec is probably a stack variable where as "20" etc. will be in the .data section, so they will never be equal in that case. Unless the program pushes strings about [for some strange reason], in which case they might well get coalessed by the compiler .
Admin
Just because Java lets you do this doesn't mean you have to. Also .Net has this as well, or at least C# has it as you can also do string1.Equals.
I actually just came across this just 2 days ago and have been wondering why anybody would treat their string as an object via .Equals when, imho, String1=="abc" seems easier to read as it follows classic coding style.
I'd love to hear an explanation why/how .Equals is better.
Admin
It seems a quick Google search has answered my question, String1.Equals is MUCH faster than doing a == compare, especially if you compare VB.Net's = vs String1.Compare, look like it's upto 5-6 times faster. Of course in the overall scheme it doesn't make a difference.
http://dotnetjunkies.com/WebLog/chris.taylor/archive/2004/05/18/13927.aspx
Admin
Explcitness I guess...
The main question is "What are we comparing?"
The "content of a string" or "the pointer to the memory location holding the value of the string".
For me;
String a == String b ???? What are we comparing here? (the language hides the details)
String a.CompareTo(String b) => alphanumeric comparison of the content of the string (explicit content 'comparison')
String a.EqualTo(String b) => pointer comparison (explicit pointer 'comparison').
#My thoughts @ the moment of writing this post#
Marvin Smit
Admin
The comments are valid as of C99, which GCC supports. However, I don't know any red-blooded C programmers that actually use // in C.
http://home.tiscalinet.ch/t_wolf/tw/c/c9x_changes.html#Preprocessor (item 10)
Admin
>> ... reflector ...
>> And in VB.NET is & in C#
>> AndAlso in VB.NET is && in C#
> Wrong! The C# *interpretation* of And/Or from VB.Net
I wouldn't call it an interpretation, I mean in .NET the code you ship is all IL at the end of the day ... it is just that C# programmers speak with a different accent to VB.NET programmers so C# syntax is & and VB.NET is AND and in IL it is a bitwise comparison ... but you are right we were talking about VB6 really...
> and that "boolean" and "bitwise" are one and the same in VB 6's operational context
now that could well be so, at least I remember it being so in BBC BASIC (showing my age and my locale there) or at least I remember the manual pages discussing them as one and the same. i.e. "If (x=0) AND (y=0) Then" turned (x=0) into 0/-1, turned (y=0) into 0/-1, performed a bitwise and on the 0/-1's and took the result of 0/-1 as true/false.
Admin
Because, in Java, string1 == "abc" does not do what you think it does. It does not check if string1 is that string, rather it checks if string1 is a reference to the string object represented by "abc".
string1.equals("abc") is the only way that works.
Admin
I consider operator overloading to be equivalent to having two unrelated classes, both with a method with the same name, but each with different implementations. If you know your language makes use of operator overloading, you'll know to treat operators like nothing more than the funny-syntaxed functions that they really are, and not make any assumptions about how they'll affect their operands.
On another note, in VB, "And" and "Or" have double meanings, like "=". That is,
is equivalent to
in C, and
is
I have (not through choice) programmed quite a lot of VB, including trying to do low-level stuff like huffman encoding, so I'm pretty sure I've got this right.
Admin
x != any(...)
is usually wrong.
You probably want
x != all(...)
or equivalently
unless x == any(...)
Admin
I've done almost exactly this same WTF during development to set breakpoints.
Yes, I could probably set a conditional breakpoint on the if, but not always. Sometimes there are function return values involved and other nonsense that just makes it easier to break the statement down into nested if's like the original.
Having found my bug though, I'd probably put it back to the commented code.
Admin
Anyone noticed the last line?
Admin
I think you've got that backwards. x != all(2,4,6) is equivalent to 'true'
"On the other hand, had the control statement been:
the condition would fail, since it is not true that all of 2, 4, and 6 are equal to 4."
Admin
The scary thing is that Java optimizes things so that in some cases == will return true even though you created separate String objects. Because strings are immutable, doing this
<FONT face="Courier New">String a = "wtf";</FONT>
<FONT face="Courier New">String b = "wtf";</FONT>
only creates one object in memory, so
<FONT face="Courier New">(a == b)</FONT>
evaluates to true.
Play with it, reassign values to a or b and compare them with == and equals and you'll get a load of giggles out of it.
Ultimately it makes sense, but it's seriously counter-intuitive unless you figure out why things are happening the way they are.
Admin
In fact, Ada also has this feature. And the default is non-short-circuiting version for which the order of evaluating the operands is not defined. Having it this way is very natural to the person who's reading the code later.
Of course you can do short-circuited conditionals by saying and then instead of and and or else instead of or.
Admin
Let's assume that == was overloaded for String.
How would the following behave (o is an Object and S is a String)?
A. o == s
B. s == o
C. s == s
D. (Object) s == o
Try it with String o and !String o.
Admin
I think that's a little bit misleading because if you 'create seperate Objects' == will alwatys return false. Always.
A more accurate description is that Java's syntactic sugar for String literals is more complicated that it might seem. If you always use .equals() you will not run into issues. The only problem is that the String pool can lead the uninformed to think that == works like equals() for Strings.
Another way to get this result is like this:
String s = new String("test");
System.out.println(s == test);
System.out.println(s == test.intern());
The first output wil be false but the second should be true.
Admin
Ok, so in some cases == will return true even though you have two separate String object declarations with distinct names, if the two String objects are initialized to the same string.
Admin
Jeez, what an idiot.
String s = new String("test");
System.out.println(s == "test");
System.out.println(s.intern() == test);
Admin
Absolutely! Separates the men from the boys.
Admin
assembly time:
mov eax, [esp + 4]
cmp eax, 4
jnz exit
cmp eax, 5
jnz exit
cmp eax, 13
jnz exit
cmp eax, 20
jz exit
push offset "alloc"
call SelectType
pop eax
exit:
ret
anyways, i am not sure, but i guess most people didn't notice
that the if statements were being done against strings and not numbers...
funny...i wrote the code already :)
Admin
Not true. Try it. In java, the operator '==' does not compare the pointers themselves, it compares the objects to which the pointers refer. Therefore, this code:
String b = "thisString"; String a = b; if (a == b) System.out.println("is equal");
will generate the output, 'is equal'. However, this code:
String b = "thisString"; String a = "thisStrin"; a += "g"; if (a == b) System.out.println("is equal");
will not, because the reference for 'a' initially pointed to a new String object. When 'a' is altered later to become 'thisString', java does not change the reference. Consequently, '==' notices that 'a' and 'b' are references to different objects, but cannot tell that those objects are actually identical, which may be in fact what the programmer wants to know. That is why there is a '.equals()' method, which checks for String equality in the weak sense, or that the references are either to the same object, or different objects that are for all other intents and purposes identical.
Admin
The easiest way to code this in Python would be
if typec not in [4, 5, 13, 20]:
SelectType("ALLOC")
return
In Ruby it would be similar, if a bit reversed syntactically:
if [4, 5, 13, 20].include?(typec)
SelectType("ALLOC")
return
end
Common Lisp, Scheme, and e-Lisp all accept the following:
(if (not (member typec '(4 5 13 20)))
(select-type "alloc"))
Of course, I may have missed some alternative way that a more experience coder would find. In fact I probably wouldn't do it this way myself; instead I would let the type represent itself rather than having some numeric encoding for it, making this whole snippet unnecessary.
Comments and corrections welcome.
Admin
(I (love (Common (Lisp (Syntax (a (hell (of (a (lot)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
Admin
If one wanted to be a little perverse then the following is possible in C#:
<FONT face="Courier New" color=#0000ff size=1>if ( " 20 13 5 4 ".IndexOf( ' ' + sIn + ' ') == -1)</FONT>
<FONT face="Courier New" color=#0000ff size=1>{</FONT>
<FONT color=#0000ff><FONT face="Courier New"><FONT size=1>Console.WriteLine("Not Found ");</FONT></FONT></FONT>
<FONT face="Courier New" color=#0000ff size=1>}</FONT>
<FONT face="Courier New" color=#0000ff size=1>else</FONT>
<FONT face="Courier New" color=#0000ff size=1>{</FONT>
<FONT size=1><FONT face="Courier New" color=#0000ff>Console</FONT><FONT face="Courier New" color=#0000ff>.WriteLine("Found ");</FONT></FONT>
<FONT face="Courier New" color=#0000ff size=1>}</FONT>
<FONT size=2><FONT size=1></FONT>
</FONT>
Admin
I suppose I should also mention the following, but it looks a little too obvious!!
<FONT size=2></FONT><FONT size=1><FONT face="Courier New"><FONT color=#000080>if</FONT><FONT color=#000080> (" 20 13 5 4 ".Contains( ' ' + sIn + ' ') )</FONT></FONT></FONT>
<FONT face="Courier New" color=#000080 size=1>{</FONT>
<FONT size=1><FONT face="Courier New"><FONT color=#000080>Console</FONT><FONT color=#000080>.WriteLine("Found ");</FONT></FONT></FONT>
<FONT face="Courier New" color=#000080 size=1>}</FONT>
<FONT face="Courier New" color=#000080 size=1>else</FONT>
<FONT face="Courier New" color=#000080 size=1>{</FONT>
<FONT size=1><FONT face="Courier New"><FONT color=#000080>Console</FONT><FONT color=#000080>.WriteLine("Not Found ");</FONT></FONT></FONT>
<FONT face="Courier New" color=#000080 size=1>}</FONT><FONT size=2>
</FONT>Admin
But Java doesn't have pointers. It has only references. C++ has both, if you want to see how they differ.
Admin
Umm... I think your being funny... right?
You do know that the first version works the same way, and the first failing test failes the whole thing?
Admin
Admin
Funny stuff. Even worse is the RETURN statement inside the nested IF--a violation of structured programming standards. At the university I attended years ago putting a return in a place like that immediatly resulted in an "F" for the assignment. Lazy coding.
Admin
DZ: And/Or are bitwise operators. VB defines true as -1 (1111...) and false as 0 (0000...). This is how it also works for logical operations; the logical side is the one documented everywhere because that's the 90% use case, but they do that by taking advantage of bitwise operations in much the same way as C's bitwise operators can function in place of the logical for most calculations.
Some earlier versions of basic didn't have this distinction, AND/OR/NOT promoted everything to true/false.
Admin
I've read so many ABSOLUTELY INCORRECT WTF statements and assumptions in this thread about about bitwise and logical operators and operations in C#, VB.Net, and VB6 that I puked all over myself. [+o(]
YOU GOTTA BE KIDDING ME! .Net has been available for 5 years, and not 1 single post got it right. VB has been out for more than a decade, and only a couple of posters appears to actually comprehend its internals.
Especially poignant, and the biggest WTF was the post that compiled VB to IL and discompiled it to C# and came to the conclusion that doing a logical test using AND and OR in VB.Net are bitwise because they discompiled to "|" and "&"; in C# !
WTF else could VB.Nets' logical non-short-circuiting operators discompile to in C#? "|" and "&" are the C# LOGICAL NON-SHORT-CIRCUITING SYMBOLS! DOH! [:O]
Hoping to clear up the confusion so I don't have to puke on these subjects in the future, I've decided to stop lurking. Not that I expect it'll help, given Microsoft's failure of having any significant number of programmers actually understand any of it. [:'(]
I'll also clear up the confusion about the C# string comparisons "==" and "someString.Equals(someOtherString)". The subtle bugs you'll prevent if you thoroughly understand the string issues are worth reading through the rest of this tripe about logical and bitwise operators. Seems most of the Java guys already get the string issues. Maybe it's the 7 year head start, or maybe it's because Java examples typically use the .equals() construct for correctness of intent and everybody just copies what they see...
I'll get VB6 out of the way first. Because it's a no-brainer, and because just thinking about VB makes me want to puke all over again.:
As with everything else VB, the main goal is to hide implementation details from the VB programmer. That is why the help files refer to "Logical operations", even though they are bitwise.[*-)]
Simply put, VB6 can't short circuit logical operations because internally it only does bitwise operations, and there is no such thing as short circuiting bitwise operations. It only appears to have boolean operators, and do boolean logic. That is why the constant "True" is defined as "-1", not "non-zero", or "1" as many other languages do. (-1 is represented in 2's compliment as all bits on, and VB6 uses 2's compliment for negative number representation.)
Pretty simple, actually. And it works because the "If" statement compiles down to a BEQ instruction. (BranchEqualToZero), the target of the branch being the Else (or end of If block if there is no Else block).
For those of you new to programming, if you do a bitwise AND between any non-zero number and a number with all bits on, the result is always non-zero. If you still don't get it, don't worry. You are the VB programmer Microsoft loves and targets VB for, and you've picked the correct language.
Now onto the .NET languages:
Don't confuse C# with C++, which does use the operators "|" for bitwise operations and "||" for logical operations. This, coincidentally, places C++ programmers in the same boat as VB6 programmers WRT not having a choice whether or not to short circuit logical operations because it only has 1 logical OR operator and 1 logical AND operator. Of course, unlike most VB programmers, the C++ coders actually know how stuff works under the hood, because they have to.
The most important thing to understand is the .Net runtime does NOT determine whether to perform a logical or bitwise operation based on the operator being used!
The .NET CLR has a first class understanding of logical operations as well as bitwise operations. Given this, it's obvious that the logical tests below won't compile in C# because "if" is a logical operation, and you must use logical operands (Boolean types) for logical (Boolean) operations. The operands 1 and 2 are not bools.
<FONT face="Courier New">int a = 1, b = 0;</FONT>
<FONT face="Courier New">if (a | b)...//fails to compile.</FONT>
<FONT face="Courier New">if (a || b)...//fails to compile.</FONT>
And bools are not ints, and can't be used in bitwise operations. Why does this matter, and why is the subtle distinction so important? Forget the
weeksyears you spent debugging C/C++ because somebody wrote <FONT face="Courier New">if (a=5)</FONT> instead of <FONT face="Courier New">if (a == 5), </FONT>and the fact that this won't compile in C# because of this subtle distinction. Instead, make the bigger jump and understand that once a runtime is not constrained by the operator to determine the operation, it becomes possible to use any symbols (operators) they feel like for an operation, and let the operation itself decide what to do when it encounters the symbol.In plainer terms, this allows the logical operations to use the same symbols as the bitwise operations (or any other operation for that matter) w/out any confilicts. So, the C# and VB designers decided that it would be VERY COOL if programmers could decide for themselves whether or not to short circuit logical operations.The C# designers decided to do it w/out introducing a new symbol. The VB designers decided to pick some laughably hideous terms that would have about the same odds as appearing in an existing code base as Penelope Cruise showing up at my crib at 3am for a booty call.
C# designers, knowing that many curly bracers would be giving their new language a go, decided to use the double pipe and double ampersand to indicate short circuiting, aligning with behavior and syntax existing in C++ and other curly brace langs. This left the single pipe and ampersand to indicate non-short circuiting.
Let me say this one more time, because after 5 years it still hasn't sunk in. C# logical symbols are "|", "||", "&","&&", and "==". C# bitwise symbolds include the "|" and "&" symbol. This doesn't conflict because it is not the symbol that determines whether or not the operation is bitwise or logical.
WHEW! Glad I'm not an author. Writing is so painful, and I'm just now getting to .Net string issues.[sn]
The 1st thing to understand is that C# does not define any types. The C# string is simply an alias for the CLR's System.String, which is a subclass of System.Object, henceforth referred to as the C# alias "object". So, the different string comparison behaviors is of the CLR, not C#.
The 2nd thing to understand is that CLR operators (e.g. "==") are static, and static operators are not inherited by subclasses. If you do something like:
<FONT face="Courier New">object x = new string('a');</FONT>
<FONT face="Courier New">object </FONT><FONT face="Courier New">y = new string('a');</FONT>
<FONT face="Courier New">if (x == y)... //will perform reference comparison, not value comparison and evaluates to false.</FONT>
The definition of the static "==" operator as defined by object will be invoked, because string doesn't define the == operator with "object" as both arguments. Why not? Because it can't. A type defining a static operator has to use its own type as the type of one of the arguments. This means string can't define the == operator signature as ...(object s, object s). string only defines == (string, string), which means that to get value comparison you MUST use variables defined as string, or cast to string. e.g.:
<FONT face="Courier New">if ((string)x == (string)y)...//will use string's definition of ==, and eval to true.</FONT>
Where is this most likely to bite you? When you've stuffed a string into a variable or property defined as type object, or a collection with it's members defined as object. e.g. Hashtable, ArrayList, Dictionary. You then try to do a comparison such as :
<FONT face="Courier New">if (myList[3] == "foo")....</FONT> //can fail, even if you previously did <FONT face="Courier New">myList[3] = "foo";</FONT>
Moral of the story. Never use == when comparing 2 strings if you want value semantics (content is identical), which is no doubt what you want 99.9 % of the time. Instead, use the not so elegant string.Equals(), just like the Java coders do. Equals() is an instance method, which means that the limitations of static operator definitions don't apply. string.Equals(string s), and string.Equals(object o) both do a value comparison because they are overriden by the string class.
Now, go fix all the code where you have used the == operator for string comparisons, and stop groaning at the Java syntax.[Y]
Admin
I remember a python version that worked as a client side ECMA language in I.E.
VBScript also works as ECMA on the client side in I.E.
ECMA != JavaScript
Admin
No, but ECMAScript is approximately equal to BLOCKED SCRIPT
http://www.ecma-international.org/publications/standards/Ecma-262.htm
ECMA is a standards body. ECMAScript is a language specification issued by ECMA. Not every ECMA specification is ECMAScript. ECMA 334 is a vendor-independant specification for C#. ECMA 335 is a vendor-independant specification for the CLI (data types and core objects for the .NET runtime).
Admin
WTF? Why did the word Java-remove-this-Script get translated to "BLOCKED SCRIPT" in that posting?
Admin
Got it! I've gotten into the habit of putting URLs on their own line, and ending the preceding line with a colon. The forum software saw the word JavaScript followed by a colon (:) and assumed I was creating a malicious link -- which might make sense if the forum auto-generated links from posted data that would be valid as links. It doesn't.
Admin
//-comments are valid in standard C. However, they are not valid in the old, discarded standard for C (often reffered to as C89/Ansi C/ISO C89/...). The term Standard C refers to the new standard.
Admin
PHP does:
$cats = array(1=>2, 2=>3);
foreach($cats as $key=>$cat) {
echo $cat;
}
Admin
Wow. That's pretty fscked up. But then again, I guess the REAL WTF is that anyone would willingly inflict VB.Net upon themselves when there is an almost infinitely better alternative called C#.
Not that C# doesn't also have its inherent WTFs. I look forward to the day when Visual Python comes... (if it ever does) Then finally we could have an almost WTF-free language.