- 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
They are obviously wanting to simulate an IF-ELSIF-ELSE structure, and they must think that this SELECT CASE TRUE makes the code shorter or somehow neater. I can't think of any other possible reason for this madness. In languages with braces and whatnot, a SELECT/SWITCH can make it shorter, but I don't really believe that's what is happening here. :p
Admin
For those of us that aren't VB programmers, can someone explain what exactly Select Case True means?
Admin
It will go down the list of cases until it finds one that evaluates to true and then execute it.
I am guessing that in VB the 'break' is implicit?
switch ( true ){
case a == b:
//blah
break;
case c == d:
//foo
break;
}
means
if ( a == b )
//blah
else if ( c == d )
//foo
Admin
That means it will hit the Case line that evaluates to True.
Now, to be completely fair, Select Case True is currently necessary in VB.NET to do Type evaluation in a Select Case construct:
Select Case True
Case TypeOf MyObject Is MyType
Etc..
End Select
Clearly, of course, one could use If/Then/ElseIf..
Admin
Admin
Forgive my noobishness, but isn't use of a COM object a WTF in and of itself? Something that is to be avoided if possible?
Admin
Admin
What exactly is the complaint about this code? "It looks strange" is a weak reason.
Switch statements are equivalent to if/elseif/elseif/.../else. Some languages (like Perl) do not have switch statements at all.
The CPU treats everything like a goto in the end, but nobody would argue that everything should be done with only gotos. So why should all switch statements be done with only if/else statements?
Admin
You are correct.
Admin
Not really, and not that uncommon when it comes to logging in (authenticating against a domain?)
Admin
I can't really comment on whether this is a WTF because all VB code looks like a WTF to me. [;)]
But switch case is not equivalent to if-else in all languages even though it can generally be replaced by them. Switch case statements are generally used in Java because they are 'faster' than chained if-else (at least theoretically.)
Admin
We're not saying all switch statements should be done with If/Else statements. But Select Case True or switch(true) robs the switch case statement of any space-saving benefit it would have while making the code more confusing to read.
Anonymous software guy has it pretty well.
Admin
That suggests an especially evil variation:
Admin
The WTF is that switch should make a choice based on the variable supplied. That is its purpose. It should not make a choice based on which complex case evaluates to a given constant. This makes the code hard to read, because it is not longer clear from the switch head what is done.
Praise C/C++, where switch only works on constant cases :)
Admin
For one, it was totally unecessary to even use "select case true" in this example, as software guy pointed out. That would be my complaint about this code, exactly. Plus, doing something that looks strange, whilst there is a perfectly well accepted non-strange-looking way of doing the (in effect) the same thing, it's a bad idea, because it effects readability for one, and can put silly notions in to the less informed mind (like a fresh junior dev or something).
"Keep it simple, keep it safe" my grand-daddy's lesbo mothers friend use to say.
Admin
I agree - the code does look strange, and anonymous software guy shows the way the select/case should be coded, and the unsafe error messages that are displayed are not good either - but code itself isn't much of a WTF.
Now, the clearing out of strings, that's a different story....
Admin
use Switch;
Admin
It's amazing how often I see this type of thing in our contractors' code. Initializing things before they are initialized.
This is really annoying when it's a local variable because the compiler will tell you if there is a path that doesn't ensure initialization and doing this defeats that feature.
Admin
I've been told by a couple people that switch(true) is actually a more efficient method of handling some types of multiple exclusive tests than with if/elseif/elseif/elseif/elseif/ese. I don't recall the explanation exactly; something about the structuring of switch/select "tables" as seen by the compiler/parser being a more efficient way for the compiler/parser to jump to the correct peice of code.
So to me the Select Case True is not such a strange thing to see.. BUT in this code, that doesn't stand up.. What really is WTF about this is that they did not "Select Case objLoginValidation.error" since that is the only variable they are comparing. In this case, a Select Case True is not properly used for the optimization I heard of, if it exists.
Then to be even weirder, they provide "Case Else" for "Select Case True". It's like putting random checks in your code saying
If(true == false) { Error('OMGWTF Somethings wrong!'); }
Admin
ok, I agree the above is a WTF b/c it is more readable to have
but I have used select case True in the past. I evaluate code on efficiency & readabily (in that order). If two methods yield the same result with the same performance, I'll favor the more readable code.
So, in this instance:
I find the select case slightly more readable (IMO).
Admin
I think the time on the web server is off. The timestamps on the posts look wrong.
Admin
Looks like GMT (or the DST version maybe) to me.
Admin
If I'm not mistaken, "Case Else DoBlah" on a "Select Case True" doesn't mean, "in the case that True is not True, DoBlah" but rather, "in the case that none of the above conditions evaluated to True, DoBlah."
As for at the second part of the WTF: When I was in college taking computer science courses one of my professors told us about a bajillion times each semester to always, always, initialize our variables explicitly. Now, even though I'm out of college and I know that that isn't always necessary, I still find myself doing
every now and then.
Admin
The optimization of switch case is that if you take an integral type and switch on it, the compiler can build a 'jump table' that allows if you jump directly to the correct instruction without check the preceeding cases. Like if you are testing 1, 2, 3 and 4 and you pass in 4, it can jump ahead 4x memory slots to the corresponding instruction (this is a very oversimplified explanation) instead of check 1, 2, and 3.
By the very nature of the select case statement, it cannot have this optimization. It is, as far as I can tell, purely syntactical sugar.
Admin
I'm not quite sure whether this is serious or a joke. It is actually a poor security practice to explain why authentication has failed, since it gives an attacker useful information.
Admin
We have a lot of people who like to do this in java:
They thought that if they didn't set everything to null before the method returned, the objects might never get garbage collected, because that method had a reference to them....
Admin
I'm surprised there are some defenders of the Select Case code. Actually that's a lie, I'm never surprised. I see some of the strangest code defended on a regular basis.
Does the code compile? Sure. Will it work? Yep. Does it look weird? That's an opinion issue. Is this how "Select Case" was intended to be used? Absolutely not.
It's that last part that makes this a WTF. If/Else If/Else and Select Case are both selection structures, so you may be able to swap them out in just about any situation. The point is that If/Else If/Else was intended for making comparisons on different sets of circumstances or groups of data, and Select Case was intended for a limited set of options for a single data value.
'An If statement works better for this kind of criteria
If MyAge > 60 Then
ElseIf MyAge <=60 And GotAgoldWatch = True Then
'Use selection struction for limited, predefined possibilities
Select Case CurrentDayOfTheWeek
You could always use a For or Do loop to add two numbers together (loop through, incrementing your variable as many times as the number you want to add to it), but why would you do that when you can just make that plus sign do what it was intended to do? Just because it isn't broken doesn't make it OK.
Admin
One of my favorite Perl features.
Admin
Obviously in this particular case, Select Case objLoginValidation.error should have been used.
Nonetheless, Select Case True can be a useful feature in VB 6. It allows lazy evaluation.
<FONT face="Courier New">If x = 1 OR y = 2 OR z = 3 Then</FONT>
will evaluate all three conditions in VB 6.
<FONT face="Courier New">Select Case True</FONT>
<FONT face="Courier New"> Case x = 1, y = 2, z = 3</FONT>
will lazy evaluate (so if x = 1 then y and z won't be checked). Note that the comma is essentially equivalent to OR.
Admin
I have never seen that documented anywhere, but sure enough it's true. VB is known for not having short-circuiting, but I'll be damned if it works in the Select Case situation.
Admin
OOo, I didn't know that. That's a pretty cool trick--short circuit evaluating in VB6.
I sometimes use Select Case even when there is only one real 'case' I am interested in. Like when I have to check for a range or set of values. Instead of
If medCode = 320 OR medCode = 331 OR (medCode => 412 AND medCode <= 420) OR medCode = 499 Then
'Do stuff
Else
'Do something else
End if
I can do:
Select Case medCode
Case 320, 331, 412 to 420, 499
'Do something
Case Else
'Do something else
End Select
This is especially helpful if there are 30+ valid values to check.
I wish I could just use the SQL "IN" syntax:
medCode in (320, 331, 499)
Admin
Admin
I personally am quite fond of the SELECT CASE TRUE structure in VB (though I don't use it, I have seen it used in code I have maintained.)
I've also seen some gothic (as in elaborate) examples of its use. For instance, there is a guy in the newsgroups (go find it yourself) who demonstrates the use of SELECT CASE TRUE for performing sanity checks in a function. Code runs something like this:
SELECT CASE TRUE
CASE Err.Number = SOME_KNOWN_ERROR
' Deal with the known error
CASE Err
' Deal with some other unknown error
CASE iSuppliedValue = 0
' Deal with some non-supplied value
CASE strOutputFile = ""
' Deal with lack of filename
...
CASE ELSE
' Proceed with normal code.
END SELECT
The argument is that this makes it unnecessary to use EXIT FUNCTION statements, or otherwise play with the flow, and that it is easy to add new conditions to the code later.
HOWEVER, the biggest problem with SELECT CASE TRUE is that it is not supported in most other languages. This would make rewriting the above code for another language a bit onerous. So I decided to not use the construction myself.
Admin
Me too. And I still do it a lot (although not in SQL). I get that there isn't any real advantage to doing it in many cases, but does it cause any significant negative impact on the code in question? I'm honestly curious because I have the habit, and I want to know if I'm doing something truly embarrassing--I already generate my share of WTF candidate code as it is.
Admin
I'm not sure I trust that code since a mathemetician once told me that 1 + 1 = 3 for sufficiently large values of 1 :-).
Admin
did you forget your sarcasm tags? [:p]
Admin
Looks like the programmer was just wishing they could use Lisp.
Admin
"I have never seen that documented anywhere, but sure enough it's true. VB is known for not having short-circuiting, but I'll be damned if it works in the Select Case situation."
I believe Code Complete makes mention that changing if-then-elses to switches speeds up VB code. Where as it drastically slows Java code. If I manage to be able to leave work tonight, I can dig up the benchmarks they provide otherwise I'll leave that as an excercise for the reader.
Admin
I have not looked at VB.Net but this is a truely VB again - I mean having a valid language statement like select case true just boggels the mind Maybe we should rather WTF the guy doing the language semantics.
But on a more objective note - back in the old days .... now I really mean long ago when I was young and Intel was still doing 4 bit processors, memory was stil a factor in programming and tight code was cool, switch (select case or what ever - depending on the language) statements resulted in neat jump tables when the compiler started spitting out machine code. Most of the time this generted more efficient code than any if else elseif bla bla bla at nausium would generate. My $0.02
Admin
Gentlemen,
Calm down. I agree that to a non-VB6 guy this looks weird. But there is a perfectly valid reason for using type of select statement -- You get INTELLISENSE.
The moment you type in
the enum intellisense pops up. If you coded it the "correct" way:
Select case objLoginValidation.Error
case LockedAccount
case InvalidLastName
...
you would get no Intellisense whatsoever.
Admin
Maybe this means that intellisense isn't always intelligent and doesn't always make sense? ;)
Admin
Freaky. Delphi is smarter, then. after you type case SomeExpression of and press Ctrl+Space, you get a list of the possible values to use. Quite helpful.
Admin
You would actually get intellisense... in VB.NET
Drak
Admin
Actually this is not really a bad practice, maybe a strange habit in this case, but clearing strings is often enough used (eg.: in C++). If you don't, strange things can happen.
Admin
IIRC, I have seen example such as this in the MSDN. That's how you are SUPPOSED to do it (at least according to M$).
The again, the MSDN is also a WTF in my opinion (especially dynamic help!!) These days I have two versions of the MSDN on my machine (one for VC7 and one for VC6, because the VC7 prefers to give me .NET junk instead of the standard C++ functions) and I still can't find anything. :(
Anyway, doing something just to please intellisense is senseless (pun intended) and a WTF all by itself. Please don't program to please intellisense. Pretty please.
Admin
Very nerdy stuff below. Not for the faint of heart !
It would still be more efficient, in most languages. You have to understand that VB (up until 4 (and again since 7)) was an interpreted language (just like Java). In non-interpreted languages, nice and neat jump tables makes sense, but when the interpreter has to interpret the code, the switch takes longer to execute. You don't really notice any significant (and by significant I mean microsecond) difference.
e.g.
;switch case example
; switch (xxx)
mov ax, [xxx] ; set ax = the value of xxx
;{
; case 0:
cmp ax, 0 ; see if ax equals 0
jz lb_lable1; if ax equals 0, jump to lb_label1
; case 1:
cmp ax, 1; see if ax equals 1
jz lb_lable2 ; if ax equals 1, jump to lb_lable2
; default:
jmp lb_default ; else, jump to lb_default
In native code, the processor can simply jump to the correct location.
In interpreted code, the interpreter first has to figure out where each of these labels will be, and then tell the processor about them.
In interpreted code, the following will be faster on average, provided the first option get's chosen more often than the last option (meaning it doesn't have to go through all the if-else cases)
;if exaple
;if (xxx == 0)
mov ax, xxx
cmp ax, 0
jz lb_label1
;else if (xxx == 1)
mov ax, xxx
cmp ax,1
jz lb_lable2
;else
jmp lb_default;
If the first branch is taken, the interpreter only has to craete one jump point and make the processor jump there.
The other issue with the intepreter is that there are context switches and paging involved, which slows things down quite a bit.
These days, the official M$ line is "Who cares about resources ? Let your resources run out ! That means you will buy another PC, which will probably come with a copy of Windows(tm) bundled and make us some hard earned $$$$ !!!"
Admin
That's nothing. Wait until you play with
Makes a wonderful replacement for
Admin
At least the 2005 DevStudio has an intelligent intellisense - there you do not need to revert to this extreme to get a list of possible values
Admin
I think the reason for this is that some primitive languages required that the contents of each variable be terminated with a NULL character so that the language would know when to stop reading. When assigning a value to a variable that already contained a value only the number of bytes actually supplied would be overwritten, so if the original contents were longer the surplus bytes would still remain. Thus the following two statements:
var1 = "FIVE"
var1 = "TEN"
would result in the contents of var1 being "TENE".
By setting the variable to '' (which was supposed to fill it with NULLs, not just set the first byte to NULL) you effectively erase the existing contents before inserting a new value.
Thankfully modern languages are not so stupid, but some college professors are still behind the times and insist on using outdated practices.
Admin
WTH? Generally used in Java? I mean - if you have it, you use it, why the f*ck shouldn't I use it as frequently in C as I do in Java, or any language that has some sort of switch/select-case construct? And anyway, someone using a case statement in Java only because it's faster has no clue about performance. Java itself isn't that slow u know, the problem is that java makes it easy to write a program in an inefficient way (C# has the same problem), and the early VM's weren't really that fast, but that changed a lot since then. When you want/need optimalisations, look at the source (not literaly [:P]) of the performance problems - which is in general the main program design - not always the implementation. Case statements should be used when comparing one variable value to multiple constant values, that's what it's there for, to make such a thing clear & readable.
And this case-statement actually de-optimizes that case-statement, since the cpu has to evaluate each "case"-value also, which ends up in 2 compares. Not that you're gonna notice this (in any language that is) with the cpu's of today, and even on a 486 33mhz, you'll never notice this, certainly when it's only executed once in a login sequence... Oh no, the user should wait 0,00000001s longer - now he's gonna have a heart-attack! [*-)][:P]
The problem with this code isn't that it doesn't work, the problem is that it's unreadable, confusing and simply a bad design. Probably a coder who thought he was doing something in a smart way nobody ever thought about, or he was maybe just messing around, having fun [:P]