- 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
On a long enough time scale, I guess ALL variables are temporary.
Kudos on the totally impenetrable variable names.
Admin
i = Integer...
s = String...
a = ???
Admin
a = Asinine [;)]
Admin
What an oxmoron ! Some one smart enough to use option explict but dumb enough to include all that crap in every page. [8o|]
Admin
See, that's genius. It will save several seconds of programmer time over the course of the project, and the only cost is the extra memory it takes to store those variables, the extra clock cycles needed to set them up, the loss of clarity from hiding the variable definitions, and the extra hours of programmer time needed maintain it.
--AC
Admin
This brings back good old FORTRAN memories:
IMPLICIT REAL*8 A-H,O-Z
Ah, those were the days...
Admin
Isn't "option explicit" kind of an oxymoron itself?
- Sumit.
Admin
Maybe every function used every single one of these temporary variables, thereby reducing the overhead for each function :D Also, they can be used to pass key information throughout the program... Look ma! No parameters!
Admin
I recently saw something like this with some C-code I inherited. I wound up rewriting the entire program, mostly out of principle. In any case, there was one header file, used to include externs that were defined in the other implementation files. No function prototypes, just extern declarations, and a shitload of global variables.
To be fair, the guy was just learning C and this was his first major project in the language; I made several of the same mistakes when I first learned C a loooong time ago. I still marvel at the fact that he figured out how to use externs and pointer arithmetic, but not the preprocessor, or function prototypes.
Admin
Include files in any language are the work of the devil.
Admin
Pointer arithmetic is a WTF in and of itself. Works great in assembly, but puts you in a world of hurt in C++. How he learned extern is amazing... he might have just been dumping keywords until one compiled properly.
Also, were you guys using Visual Studio? If you use any of the wizards, they almost *force* you into using .h/.cpp files and prototypes. I can't even imagine how a GUI would have been implemented.
Admin
a = Array, presumably. This guy must have taken "how to write unmaintanable code" literally.
Admin
WTF is wrong with pointer arithmetic? Just because people abuse it to create WTFs doesn't mean that it is a WTF. Same applies to VB, etc. Another clichè comes to mind: Don't use it, if you don't mean it :) It doesn't solve all the world problems, but makes some of them easier to solve.
Oh, just to finish with a last clichè, since I'm on a roll here: Guns don't kill people, people kill people (with guns).
Admin
I was thinking a=Any
Admin
It is probably inspired by the "Hungarian notation".
Admin
No visual studio. I work in a research lab, so we're mainly a linux/unix shop and if we do write for windows/mac, we use unix tools to do our porting. Using function prototypes in C/C++ is a Good Thing(tm) since otherwise, the compiler assumes the return type of functions is int. It's just the way the language is.
Pointer arithmetic can be elegant at times. Portable byte swapping routines for endian issues are a good example. The thing that got me about the pointer arithmetic in this case was that I saw no less than 3 different idioms for accessing elements in an array within 5 lines of eachother... for example, I'd see something like
foo[i] = bar;
*(foo + i) = bar;
tmp = foo;
tmp += i;
*tmp = bar;
What made it worse was that the arrays represented two dimensional data. Maybe I should submit some of the more egregious code sometime. I saved it for posterity's sake.
Admin
By that logic, everyone should be allowed to walk around with personal nuclear weapons or spray cans full of VX nerve gas. VX nerve gas doesn't kill people. People kill people. You'll get my VX nerve gas when you pry it from my cold dead hands.
Not that I think everything that can be used improperly should be eliminated it's just that your argument is a little specious.
Admin
Well, as an argument for allowing people to carry guns, it's bad. The original purpose of that argment was to dispel the notion that guns are inherently bad.
Admin
Most people have commented on the fact that it appears to be hungarian notation at the beginning of the variable names, but they are all declared as variants (VB6 no type declaration assumes Variant). So the hungarian notation is just wishful thinking..i.e. I can store whatever I want in there, but the original author would really like me store an integer in iJ. So let's recap the WTF's in this one:
1.) Horrible names 2.) Included in every page. 3.) Hungarian notation - this one will probably start a flame war, but hungarian notation is a gross violation of OO principles (in particular encapsulation)...it's like calling my dog dogSpike. anybody looking at him can tell he's a dog, but then I replace dogSpike with a cat...does that mean I now rename my pet catSpike (I have a hard time remembering names, so all my pets were named Spike - jk)...leaving the name would imply incorrect things to someone who didn't look at the declaration of dogSpike who's really a cat. Instead, I'll call my pet Spike and when I'm not sure what he is, I'll look at his declaration. This is the exact same problem with this code. sTmp is really a variant. So someone may actually put a string in there, but then someone else may use it in a completely different way and voila unanticipated side effects. 4.) declaring everything as a variant. Void pointers were fun in C/C++. Fun but could be very very dangerous.
Admin
I worked with an old-timer who declared all of his variables global in the header file. Never used params, never used local variables except for counters or whatnot. We had a completely ineffectual team leader who wouldn't recognize programming standards if we hot glued them to her forehead. We constantly tried to discourage him from writing crap like that but he would argue perpetually why doing it his way was better since you never had to worry about accessing the variables. Some declarations would go on for pages and pages.
Good times!
Admin
These were all declared globally (though in a hidden away file) and used throughout the site.
I found a couple more corkers as well such as
StrTemp2=StrTemp2
and
StrTemp="content of site"
StrTemp2=StrTemp
StrTemp="more content"
StrTemp3=StrTemp
The site wasn't even a couple of pages big or anything like that, it's quite a large complicated system.
Admin
Ouch! But you never mentioned if concurrency was involved in these systems? That would make it even better :) This site is soo scaring me away from even getting a job in "the wild" (aka industry). "Forever young, I want to be forever young"
Admin
He figgured out pointer arithmetic but not function prototypes? I think that's a new definition of idiot savant.
Admin
Yep, I've used 'a' to mean Array in my code too - though I named it a little better, and more descriptive to what was contained in the Array than aTmp6!?!
Admin
Or just an assembly programmer.
Admin
This Joel on Software article makes a good point in favor of Hungarian notation, but it is not the kind that you are used to.
Instead of using a prefix to indicate the type of a variable, the prefix should tell you something what what is actually in the variable.
int iCount = 0; // Redundant, we already know it's an integer
String usUserName = getParm("username"); // us means "unsafe string"
String sUserName = sUrlEscape(usUserName); // s means "safe string"
If you are using this kind of notation and you accidentally write usUserName to the output, you know it is a mistake, because you should never write unsafe strings to the output.
For the full argument, read the article.
Admin
Remember -- this is VBScript. Everything is a variant; there are no data type declarations in the language (same with javascript).
Actually, in VBScript, it is sometimes useful to use hungarian notation because in scripting languages w/o data types you cannot tell that Spike is a dog or that Count is an integer. This is especially handy in function argument declarations.
Admin
I'm pretty sure this code is VBScript since it's from an ASP page, and you cannot declare variables as any type in VBScript.
And yes, the hungarian notation *is* wishful thinking, but it's a little help for the developer in the right direction as to what's supposed to be in the variable.
3) True, Hungarian notation is anti-OO but since this is script language it's not OO so hungarian notation is fine.
4) - see above about VBScript.
Don't get me wrong - this code is a WTF and I agree with your other points.
Admin
Pointer arithmetic:
1)It's harder to read than [] brackets
2)No protection from going out of bounds in memory
3)By extension, you can accidentally overwrite other objects in memory
4)Harder to maintain
5)doesn't preserve well across architectures (little endian versus big endian)
6)doesn't preserve well across architectures (16-bit versus 32-bit versus 64-bit)
You can use it at your own risk, but good luck trying to get away with in our house, mr "real programmer".
And it's cliché not clichè.
Admin
What saved my ass whenever working with crufty old FORTRAN code was:
IMPLICIT NONE
or even:
IMPLICIT LOGICAL (A-Z).
Doing that would bring the bugs out of the woodwork.
Admin
1) True.
2) [] does not necessarilly provide you any protection, and in C and C++ this is not restricted to a range of values, and is simply shorthand for a+i
3) See 2
4) Agreed.
5) No more than [], see point 2. Using with void * does not guarantee results, however.
6) See point 5. Even more so with void *, but you are afforded that i+a will always advance sizeof(type)*a bytes.
Before you trash something, make sure you understand it.. ;)
Admin
Reminds me of good'ol QBasic DEFINT A-Z
Admin
This is most fun when the language usually typecasts for you, except for when it doesn't.
For example:
Const MAX_COUNT = 5
Dim counter
For counter = 0 to MAX_COUNT
If Request.Querystring("am_I_going_to_work") = counter Then
'Do something with am_I_going_to_work
End If
Next
Dies (at least in older IIS versions) because "5" <> 5, and the type-agnostic environment in which you thought you were operating suddenly (for a number of hours I still recall with emabarrassment) leaves you adrift; Response.Write is no help on this one.
Probably C# coding alleviates some of this surprise, but I haven't much time with that one at the moment.
Admin
Oh how I hated that damn assembly language. I always forgot to put the damn [] around the variables or registers when accessing the value of the pointer not the address. Brings back horrible nightmares of my college years...
Admin
I never really thought Joel's advice was all that compelling and this is another case.
The biggest problem with Hungarian notation is that it requires remembering a bunch of arcane notation can mean different things to different people. If you followed this advice, you'd need to publish a book of what all the notation means. The other problem is that the notation can easily become out-of-snyc with reality.
I still feel that good OO makes this pretty much unecessary. The problem is that most developers don't understand OO even when they think they do.
Admin
As an example, when I first looked at this, I though "WTF is an 'unsafe' String?" Its useless unless everyone knows that 's' stands for 'unsafe' and 'unsafe' means that it's not url-encoded. 's' could mean 'synchronized' for all I know.
Admin
As an example, when I first looked at this, I though "WTF is an 'unsafe' String?" Its useless unless everyone knows that 's' stands for 'unsafe' and 'unsafe' means that it's not url-encoded. 's' could mean 'synchronized' for all I know.
Admin
Sadly, not really a wtf, more of a "why???", unless in this case the w stands for where.
Mind you, its nice to not get bombarded by perversity like yesterday's two days running.
Lotta chatter about what is ultimately lame code rather than peverse (hey, asp is a scripting language, it doesn't have scope to speak of, so you might as well declare 'em all together somewhere, at least the fact that they are all temporary is well documented)
For such stupidity was grep invented after all.
Admin
Truly. It wasn't until I learned assembly that I was truly comfortable with pointers. Not sure how he managed.
Admin
Agree with 2,3,6. Although, technically, [] doesn't protect you against out of bounds errors either. I had problem 3 about 2 weeks ago (on the code in question) that took me forever and a day to find, although again, [] wouldn't save you.
With the type of indexing he was doing even [] wouldn't have helped. 4, depends on what you're doing. 5, you can use creative pointer manipulation to do byte swapping (I mentioned this previously). 1, it's syntactic sugar, but you're right.
But yeah, in general, it's best to stay away from the type of shenanigans I was seeing.
Admin
"As an example, when I first looked at this, I though "WTF is an 'unsafe' String?" Its useless unless everyone knows that 'us' stands for 'unsafe' and 'unsafe' means that it's not url-encoded. 's' could mean 'synchronized' for all I know."
Yes. (Correcting one tiny typo.)
I mean, it's part way there:
String usUserName = getParm("username"); // us means "unsafe string" String sUserName = sUrlEscape(usUserName); // s means "safe string"
But it's not all the way there:
UnsafeString Name1 = getParm("username"); SafeString Name2 = SafeString(UserName);
(Out of context, I'm not going for more useful names than that.)
If you're going to use a type system, don't get off half way. Joel strikes me as that most dangerous of people: someone with a little knowledge.
But perhaps he's put himself in an environment where the type system is half arsed.
Admin
Ah, the good 'ol days of includes, globals and no type safety.
I'm guessing iQ was always a low number...
Alex: another great title! How do you come up with these?
Admin
2+3) Yes, it does provide protection in the sense that if you go out of bounds, it wile puke on you (assuming you're actually using an array class like CArray<type> and not the crappy built-in one).
5) If you're accessing OBJECTS with [] instead of just casting them to void* like a loon and incrementing merrily along byte by byte you won't run into any endian problems. That is, assuming you're using a proper array class.
6) I guess you were agreeing with me then.
Perhaps I should have been more clear in saying using [] in the sense that you're going to use a true array class instead of merely translating all your pointer arithmatic to []. Still, using [] is still saner than not, when an array class is unavailable.
And I perfectly know WTF I'm talking about, I programed a whole videogame in Intel Assembly, and did nothing but pointer arithmatic in it. However, when coding in C++ it should really be avoided. Pointer arithmatic is the compiler's job where it can do a better bug-free job of it.
Admin
So it's not just me. Though he strikes me more as someone who thinks he knows more than he really does.
Admin
This was a small game, right? Sounds painful.
Admin
Fireside chat time everybody!
It was a 2-D space fighting game using sprites and some vector drawing, and used real-time sprite rotation. It had a fully-functional 2-D physics engine, single-player versus 3 CPU. Multiplayer TCP-IP was scrapped at the last minute. Sound effects were a bit limited as well :-/ We also had 3 weeks to complete it. It was playable, albeit barely, since our AI guy didn't write anything and I had to come up with an AI an hour before the thing was due.
I can't find the website I had for it. Maybe I'll post it later... the source code may make you just lose your lunch! Someday I hope to resurrect that POS and make it openGL....
Admin
Yes, but the Variant type does contain subtype information.
VBScript offers the VarType function to retrieve the subtype of a given Variant:
dim var1
var1 = "5"
VarType(var1) 'would return 8 (vbString)
var1 = 5
VarType(var1) 'would return 2 (vbInteger)
There are even subtypes like vbObject and vbArray.
Not a lot of fun, but better than nothing.
Admin
Whilst often I'd agree that its best to leave the compile to do the mundane work, sometimes its just better to do it yourself (today I found that the compiler I use at work produces some WTF worth interpretations of the C ... although I admitt I was trying to push it....)
Admin
</type>
It was C-code that I was talking about, Charles. Not C++. If it were C++, I wouldn't mess with arrays, I'd use vector<T> or an array class.
Admin
Ok, pointer arithmetic might be dangerous. But if you do not undertand it, you will never understand iterators.
Only random access containers have [ ]. For most of the others, iterators work almost like pointers
(in many cases they are implemented as pointers).