- 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
Uh? How's that? An iterator is abstraction that is independent of a particular implementaion technique. I don't see the link between iterators and pointer arithmetic. I hope you don't use pointer arithmetic to implement any iterators over linked lists or tree structures.
Admin
WTF ???
Are you confusing "pointer arithmetic" with iterating linked lists? Those are very different things! There's no artithmetic (that's key phrase) when you iterate a linked list.
Admin
Dude, stop copying me.
Admin
Agreed, I liked IMPLICIT NONE - my dad taught me that from the "bad old days"... helped so much with debugging.
I used it in the exams for my fortran class (oh so many years ago) and the tutor had the nerve to mark me down as he didn't know what it did.
I got out the textbook for him and explained - he did give me back my marks then. :)
Admin
Uhm... 3rd time is a charm. The syntax of accessing items through iterators in C++ may be similar to pointer dereferencing, but that's where the similarity ends. Iterators should not be considered the same as pointers because they are an abstraction to access elements in a container, not an index to a location in memory.
Admin
Charles N.: Guess you misunderstood what I meant. Which I can understand with the rather harsh language I used [:$]
I was not advocating that you should use pointer arithmetic all the time, just that sometimes you need to use it. For example C# has the "fixed" statement which makes pointer arithmetic available, but I don't think I've used it more than once in a P/Invoke scenario.
Admin
You need it how?
Admin
Have you ever thought of this angle - this person just saved on using an obfuscator. Cryptic names, no detectable type, variables not declared where they are being used ..... ( And just before I end up with a drill in my head - I'm just joking ... )
Admin
I'd of guessed the problem with using global variables as if they were local was the bugs you'd get from calling functions that use the same variables but in a different way?
How about:
Dim ii;
...
sub one // ok, this is pseudocode, forgot all my VB years ago..
ii = 1;
end sub
sub two
for ii = 0 to 10
one // arggh!
next ii
end sub
Admin
Ok, so, you have made a new type, but you do not MENTION the type each time you reference the variable...
you have
UNSAFESTRING aString = getParm("username")
fine, on that line, you can see that the contents of aString is unsafe.
But you use the string 100 lines farther down...
write aString
not a clue as to its safeness...
including the "us" prefix in the name means that its there everywhere. the whole point is that this is a little bit of information about the contents of the variable that is carried with it everywhere and is easy to see. burying this information in a typedef or class definition is less than useful.
<RANT>
As to "a little knowledge"... do you know who joel is, do you know what he has done?
do you know what he is doing now?
I am not one to accept someones credentials at face value until they have shown that they can think, but damn... Joels credentials are impecable. Read his books. then start spouting about "a little knowledge".
</RANT>
Admin
They *are* the same thing. Iterators use the same syntax as pointers because they're a generalization of the concept. If some platform decided that pointers would be bound-checked, that would be perfectly fine. You're only guaranteed that pointers to actual elements and one past the end of the array will do anything useful. (including advancing it two past the end and backing up, that could fail even if you never dereference it) So pointers could, in theory, be completely safe. They usually aren't simply because that would kill performance.
Furthermore, I don't believe that iterators are required to have well defined semantics when you try to push them past the ends of the container either. If that were the case, pointers couldn't be used as valid iterators. If you think iterators are somehow special and safer than pointers, try using one after it has been invalidated. Get an iterator to an element in a linked-list, delete the element, write to it through the iterator. Does it stop you? Where does that stuff go?
Admin
So how are you supposed to write function libraries in ASP? Or are you suggesting that you repeat your functions in every page?
Admin
Wait for it.....
BWAH ha ha ha ha...ha.ha...<thump>... Sorry. Just laughing my arse off....
Admin
I'm very torn on the whole Joel thing - I think he's wrong about Exceptions, but the prepending variable names based on status has a certain something. I haven't read what he's done, I'm just going on his arguments and just don't think they hold up that well. Old/experienced programmer != good programmer.
The trouble with the SafeString and UnsafeString idea (at least in Java) is that String is final - so you wouldn't be able to use these classes without mucking about exhuming and inhuming the wrapped String left, right and centre..
Prepending the variable names avoids this, and the idea is it's part of your coding standard from the beginning, so everyone knows what they mean. I don't think I'd do it myself, but I can see that perhaps in certain situations, it could be useful.
Admin
No. Visual Basic is the work of the devil. Include files in any other language is his hobby.
dZ.
Admin
Don't forget the debug time when one of them is checked before setting and inherits the last value set...
Justin.
Admin
To be fair, if you hot glued programming standards to someones forehead then the only way they could read them would to be to look in a mirror, in which case all the words would be back to front and recognising them as a programming standard might be a bit much to ask.
Admin
Funny, I was one of those that actually enjoyed Assembly Language class back in college; primarily because I already had a background programming in ASM, and felt comfortable using it. I started programming in ASM back in the good ol' C=64 hayday, even before I learned C, so by the time I started with the latter I was able to appreciate its simplicity and beauty of design. But I digress...
Admittedly, I was probably the only one in ASM class that actually liked it and took each assignment as a challenge to attack with a bit of lateral thinking.
I find the mind-set of the current generation of programmers coming fresh out of college, disturbing. Everything *has* to be the way they learned it in college, there is *only* One True Way of performing a task, and it is probably using the One True Language they bought the text book for. Everything and everyone else is wrong, particularly those philistines who dare to diverge from the canned, rapid-application-development, gui-builder, point-and-clicky, garbage-collecting, typeless and pointer-stunted, dialect-du-jour.
For this I emphasize my believe in a very huge difference between "programmer" and "coder". The former is a specialized tradesman, the latter sheep-minded robot.
dZ.
Admin
I'm sure it's "Guns don't kill people, rappers do. I'm a rapper and I'm gonna kill you!"
Admin
Thanks. I hate typing, and you've saved me a lot of keystrokes.
Admin
...100 lines down the compiler will emit an error, for there is no write operation defined for type UNSAFESTRING. This is so much better than arbitrary prefixes in variable names, and exactly something the machines were originally designed for. No matter how many code reviews you do, you might miss that someone has violated the name prefix rule or performed an illegal assignment and you're busted. The compiler won't miss it.
And using the compiler to read the source code is hundreds of times cheaper than four pairs of eyes reading the same code as well.
Code reviews have a purpose, but this is not one of those.
Joel is wrong, and no matter what he has done in the past he is still wrong.
Admin
Well-said. Ah -- the 6502 CPU. Gotta love 8-byte programming !
I think about the amount of bit shifting/masking and computations required back in the day to simply plot a single point on the C64's 320x200 graphics screen; you simply had to know what you were doing to accomplish even the most trivial tasks. Then I think of the programmers today with the huge libraries at their disposal who write code this like this .... it's pretty sad.
Admin
oops -- 8-bit programming!
Admin
There's a language feature in Perl that shows how this can be done.
It's called taint tracking.
Effectively, every single variable has an extra (boolean) attribute, which is whether it's due to outside input or not. Read a string from console or file or whatever, and the variable you read into gets its taint flag set. Add this string to another, and the result also gets its taint flag set.
When you actually use the variable in a potentially unsafe way, the system can check the taint flag and stop it happening.
"Joel is wrong, and no matter what he has done in the past he is still wrong."
This is my feeling as well. I don't trust anyone to be right all the time. I prefer to examine the arguments, seewhat others tink (for or aginst) and come to my own conclusion. In this particular article, two arguments are trotted out, and I find both faulty.
(If someone is usually right, then I will pay closer heed to their arguments than I would if they were usually wrong.)
I do find it interesting that this is possibly the only article I've ever seen giving a halfway reasonable defense of Hungarian Notation. It's rather spoilt by being coupled with an argument against exceptions - I've seen a couple of other articles against exceptions and those others were not worth the pixels they were written on. Mostly because they always implictly (not explicitly, oh no) ended up recommending ignoring all errors. If the article had been just "Hungarian is OK, really", I would have nodded my head and said, "OK, Joel, if it works for you".
Admin
'100 lines down' is where the problem lies. Not the lack of some obfuscated notation scheme.
I've seen these types of schemes over the years and I've never found them valuable.
I just read his bio. I don't see anything that impressive. He worked at Microsoft, which problaby explains why he wants to resurrect the Hungarian nightmare.
What's so imppecable about them?
Admin
I don't agree with Joel's stance on exceptions but I do agree that writing good exception based error handling code is hard, that does not make exceptions evil.
I do see his point here about hungarian notation. I think the two posters above have missed something. There is no type UnsafeString. Strings cannot be extended from (in most OO languages), and for good reason.
The point here is if you do something like
String name = getParam("name");
and x amount of lines later you use name to write to the output you now have a situation where you are vunerable to having JavaScript injected into your code.
If you have
String usName = getParam("name");
Then when you see:
write usName
you can train your eyes to say, hang on a second that's an unsafe string I probably shouldn't be writing it to the output without encoding it first:
String usName = getParam("name");
...
...
...
String sName = Encode(usName);
...
...
write sName
That's all his point is. It's not a catch everything, it just describes how the name of the variable can have a prefix that describes its nature.
Admin
say NO to code reuse
Admin
Which is all well and good until some bozo comes along and changes "String sName=Encode(usName)" to String sName = getParam("name"); in an effort to "save a few cycles"
Many lines later, in a nother section of the code, Joe Safestring looks at the line:
sSQL = "select * from users where name = '"& sName &"' // This should be safe, becuase the variable says so.
and wonders why he's dealing with a database disaster (all dropped tables and several trojans running on the server SQL Server was residing on) then answers to his boss "Gee, I could have sworn that string was safe for database use, it even had an s on it saying so"
Admin
No, because as the other guy said, unsafestring defines no method that write can operate one, so write will not compile.
That is:
unsafestring username = getParam("username")
50 lines latter:
sql = "select username from table where username=" + username.getSqlSafe()
50 lines latter:
write username.getWebSafe()
And so on. SqlSafe quotes things differently from WebSafe. Depending on your needs, you might design your classes differently of course.
Joels point is the best argument for Hungarian I've ever heard. If you can't design classes as I presented, then it is a good work around.
I do find it a WTF that your example used "aString" for a variable name, when getParam was given "username". I understand this is pseudo code, but you still shouldn't do that. Either make the variable name meaningful, or do getParam("aParam")
Admin
I think you missed my point where I note that I don't look at 'us' and think 'unsafe'. I might thing 'United States' or 'unsynchronized' or most likely I just won't know. The problem is you take one example and people look at it and say "Oh yeah, I could remember that." But if you follow this advice all the time, you'll end up with hundreds if not thousands of prefixes. You'll have to start cataloging them. New people on the team won't know WTF they mean so they will be busy trying to decipher the code instead of working on it. I know because I've come into a team where this type of thing was done.
http://mindprod.com/jgloss/unmainnaming.html #29 & #30
/** the raw (unencoded) name */
String name;
If the above isn't good enough, the either your method or class is too long or your classes are poorly designed (too much inheritance, too many variables, scope too large, etc.)
Admin
A name of a variable should describe it's nature. It should be used to identify a piece of storage. For example,
Good variable names:
Map users = new HashMap();
or
List users = new ArrayList();
versus bad names
Map userMap = new HashMap();
Map mUsers = new HashMap();
Map mapUsers = new HashMap();
or
List userList = new ArrayList();
List lstUsers = new ArrayList();
List lUsers = new ArrayList();
Simply using the name users describes what it is (a group of 0 or more users). The examples of poor naming describing the variable's nature. With any modern IDE if I really need to know the type of users I can hover on the variable name and figure out what type it is. I can also usually figure it out based on how it is being used. Also, if I'm writing code with tight cohesion (a method does one thing and does it well) I will have tight compact methods which means I'll never be more than a dozen or two lines from where it was declared (instance/class level variables you may have to search a little bit further, but again your classes should be relatively small if they're cohesive). That then leaves ancestors as being the trickiest to find if you're not using a modern IDE, but if you are declaring lots of protected variables in your code, you should really re-evaluate your class structure.
Moral of the story...names are used to identify something. It would be like me saying that because a woman's name is Mary (which means pure of spirit) she'll be a goodie-goodie. That's not necessarily the case. Mary is simply the identifier that was assigned to her so people would know how to refer to her directly. Instead lets name her goodieMary, boringMary, or trampyMary depending on her personality traits.
Admin
In the context of pointer arithmetic, they are not the same. Pointer arithmetic assumes contiguous memory addresses and random access to any element within that defined space. You can't make that assumption with iterators in general.
Please point me to where I said iterators were safer than pointers.
Right. I didn't.
I said they were different from pointers. That's it.
Admin
You apparenty do not understand that Iterator is a design pattern. Read the Gof Design Patters for more info. It's not a generalization of pointers. Iterator, for example is a fundamental Java class and Java has no pointer arithmetic and references (pointers) are completely safe and it doesn't kill performance.
You also seem to be confused about the difference between using pointers and using pointer arithmetic. Pointer arithmetic is when do things like increment a pointer. Pointers can be used without doing any pointer arithmetic.
A properly implemented Iterator should not just try to reference memory that is beyond it's container. It should throw an error if it is used after there are no more elements.
Admin
I can't believe somebody with a long background and who appears to be relatively intelligent is recommending using hungarian notation to deal with data tainting. I mean, what the f*ck?
Perl does data tainting out of the box. So does Ruby. Most languages can be used to implement data tainting relatively simply so that injection attacks and the like are close-to impossible.
I mean. What sort of moron sees AND RECOGNISES a potential security problem with unvalidated user-supplied data being used direct, and then thinks "I know, we can fix that by changing the NAMING CONVENTION WE USE FOR OUR VARIABLES".
It appears that he used to work for MS. No f*cking wonder their various intarweb software are such marvels of security.
I dread to read anything else this guy's written. I'm too afraid of coming across the bit where he recommends storing SQL that needs to be persisted across sessions in a cookie named '_usSQL'.
Simon
Oh, and hungarian notation is the work of the devil. Kent Beck's "Smalltalk Best Practice Patterns" explains why.
Admin
But pointers and iterators use the same syntax in C++ to access elements! They must be the same!
Admin
Damn! You've got me there. I guess I should'nt even bother giving an example of how one might implement a LongIterator that returns the bytes from a long and how that wouldn't need to use pointers.
Admin
What's with all the people flaming hungarian notation? I was "forced" to use it when I got my job, and now I prefer it.
Take for example, a variable called Temperature.
if you prefix to
dTemperature
you know it's a double that exists only within the scope of the method
if you prefix it to
m_fTemperature
you know it's a float that's a member of a class
This allows for very easily recognizeable variables, in terms of type and scope, no matter what kind of reader you're using, from emacs to Visual Studio 2005. It's also faster than "hovering" over a variable or scanning for where the variable is declared.
Admin
Or you could just look at the declaration of the variable. All that info is redundant. Unless, of course, you aren't using a strongly typed langauge. Then it's pretty much the only way to remain sane.
I like the 'unmaintainable code' real-world example: a_crszkvc30LastNameCol
Admin
What if you don't want to go to the .h file to see the declaration? Or don't want to scroll up a screen to see the declaration of the variable? It's a little redundant, but speeds up code-reading and code-writing time. With intellisense when I type m_d I get all the doubles available for the class I'm using. It's quite convenient! And only an idiot would create hungarian notation like that above monstrosity (note: I have a feeling it was written by microsoft).
Admin
Let me rephrase. I understand that it's a useful tool in certain cases. I just get annoyed when people want to use it languages like Java where you should never have to go too far to find the declaration. Also, you usually don't get too far if you are confused about the type.
Admin
Decent hungarian (not sOut or oDbConn) is useful in environments where the only semantics your editor gives is syntax highlighting, if that.
Hungarian is useless in environments with advanced IDEs that can display full declaration info with a mouseover or caratover, and hop to other instances quickly. Unfortunately these IDEs don't have optic interfaces that let simply reading a variable name give you all its info yet, but we'll get there. On the other hand, it doesn't really hurt these IDEs, since you should be able to type the first letter or two and find it in the list. So it should be an entirely moot point, aside from preferences.
I just wish I could figure out where IDEs get the idea that alphabetical order drop-downs is in any way a usable UI. Even though String is the only thing I've ever selected the last 40 times I typed s or st, thanks for making me scroll through a halfdozen other types that start with it each time!
Admin
You must be talking about Java when referring to "most OO languages", right? Java is the WTF on its own by having the boolean type, but not user-defineable enumeration types or other types. I mean, if they go through all the trouble to create an enumerated type called "bool" or "boolean", why not have generic enumerated types as well? Or types as such?
Seeing code like
int day = Calendar.getDay();
object.setDayOfWeek(day);
makes me want to cry. A real WTF imho.
In my preferred language(tm), an unsafe string would almost as easy as
type Unsafe_String_Type is new String;
With this the compiler would barf an error for any variable declared as Unsafe_String_Type if I tried to pass it along as String (the language is Ada, BTW, widely used in safety-critical stuff).
Admin
When I was a VB/C/C++ developer I swore by hungarian notation. The tools weren't all that helpful back then either and that's they you did it in those languages. A former boss of mine required people to use m_ for module level variables in VB, a_ for method arguments and l_ for local variables. We got him to let us quit using a_ and l_ because that seemed a bit overkill (he defended it because of VB's whole ByRef and ByVal shenanigans - if it was a_ be careful).
When I made the switch to Java I made my team use hungarian notation for the first few months, then we adopted the "When in Rome" philosophy. From there it grew on me.
I believe it's in Joshua Bloch's book, Effective Java Programming Language Guide he gives a pretty compelling argument on why hungarian notation is bad (similar to my first post in this thread, but more eloquent).
I go back to my earlier post about cohesion (do one thing and do it well). If you were to look at most of my code, the methods are very short (I think the longest one I've written in the last couple of months was about 30 - 40 lines). With the screen resolution I use that's less than a full screen. So it takes me half a second to determine if the variable is local or not. So the m_ is a waste of keystrokes, if I didn't see it in the relative area, it's located someplace else.
I also code under the principle of it can get of sync it will. Javadoc gets written last. I only write inline comments when I'm doing something reall tricky and then I re-evaluate my approach to see if I can make the code more self-explanatory. When my code goes through a thorough code review, anything that doesn't make sense on it's own gets refactored or gets an in-line comment if there's a time crunch. Because every time I've had to maintain someone else's code (and some of the WTF's I wrote in my early days) one thing I always noticed...the bloody comments didn't match what the code was doing! Then I also noticed that variables named bytAge was changed to an int but the named hadn't been changed.
In a test-driven world, the final code itself becomes the design artifact - sure you have detailed design documents, but they're out of date as soon as the first line of code is written, so I treat DD's as a snapshot in time. When I want to know what's really going on, I read the requirements and the code. Sequence diagrams and class diagrams are nice, but if they're not reverse engineered out of the code I don't completely trust them, because chances are they're out of sync or they're how the author intended to build the system, not what he ended up with (refactoring is fun).
So my distaste for hungarian notation comes from having to maintain old code that's become the red-headed step child that nobody wants. Wrong information is worse than no information.
If you are unfortunate enough to work in a language that doesn't have type safety, you have my sympathy. Hungarian notation in that case is only wishful thinking. Of course, that's why I moved away from those languages, they usually caused me more headaches than they cured.
I sometimes agree with Joel on Software and sometimes I don't, but at the very least he stimulates conversation which triggers healthy debates (such as this one).
Admin
Types == Classes in Java. And you can define as many classes as you like.
Java is an OO language almost but not quite. There the primitive types but everything else is an Object type.
Yes the java.util.Calendar class is a WTF. Someone said it was taken from this OS that was never finished. I can't remember the name of it.
Actually the new version of Java has a language support for typesafe enumerations which are OO enums, basically.
In Java, you can define a class in the middle of a method if you want that wraps a String. In Java 1.4 they introduces a CharSequence interface but it was a little too late.
Admin
I supposed another reason why we use hungarian notation that I forgot to mention is that we're using MFC in a lot of our apps, so I guess "when in Rome" philosophy applies to our code as well... if we DIDN'T use Hungarian notation from inheriting microsoft's classes, then we would be in big trouble. Now that I think about, I guess it is a pretty big reason ;)
Admin
Java does have enums.
class DayOfWeek
{
public static const int SUNDAY = 0;
public static const int MONDAY = 1;
public static const int TUESDAY = 2;
public static const int WEDNESDAY = 3;
public static const int THURSDAY = 4;
public static const int FRIDAY = 5;
public static const int SATURDAY = 6;
}
...
if (Date.getDayOfWeek() == DayOfWeek.SATURDAY)
{ TV.watch();
}
Admin
Hungarian Notation was devised primarily as a way of handling large number of persistent, independent variables (especially global variables), which is itself a WTF. As a rule of thumb, I consider any case where I have more than 8 separate variables in scope to be an indicator than the design needs to be reconsidered.
Admin
Not sure if you are kidding here. const isn't allowed in Java. In Java we use typesafe enums that look like this:
public class DayOfWeek
{
public static final DayOfWeek SUNDAY = new DayOfWeek();
public static final DayOfWeek MONDAY = new DayOfWeek();
public static final DayOfWeek TUESDAY = new DayOfWeek();
public static final DayOfWeek WEDNESDAY = new DayOfWeek();
public static final DayOfWeek THURSDAY = new DayOfWeek();
public static final DayOfWeek FRIDAY = new DayOfWeek();
public static final DayOfWeek SATURDAY = new DayOfWeek();
private DayOfWeek(){}
}
In 1.5 this is done simply with:
enum DayOfWeek {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
Admin
oops s/const/final/g
Admin
I've seen worse. I ran into an ASP app once that included a file called 'dim.inc' -- and I'm not kidding you, there were 600+ DIM statements in there. Variables like I1 to I32, J1 to J32, N1 to N31, etc.
It then proceeded to make use of -all- of them as it smashed through 3000+ lines of VBScript without a single function call.