Then your comments and code get out of sync and then you're fucked. 
Well, if that happens, you're probably doing something horribly wrong in the first place. I mean- Yes, you should comment as much as you can so the code is self documented, but it's slightly overkill to comment every last line. I usually keep certain "blocks of a task" together, separated by a carriage return and an explanation comment before the code. But I usually keep my methods short ("A method should only perform one task"), so the comments can go on top.
I
did comment every last line in this one block of code that was O{n^4) (or n^3, I forgot) because not only was it horribly slow, but I
felt it was wrong. I just didn't know what how to do it better. My coworkers let it slide because I was aware of its cost, the data set was small (the max amount of elements ever would be 31), and they
could follow every step of the code by reading the comments. Actually, they liked reading the comments. *shrug* Unfortunately, I not only don't have access to that code anymore (I've since left that job) but even if I did, I wouldn't be able to show it to anyone (even though the whole thing was open source, they don't want anyone to know that). I technically don't own that code anymore.

So, I think this is a sort of case-by-case sorta thing. You always leave a description of what you method/function does. You always leave a description of what your struct is for. You always leave a description of what a block of code will do if it's not directly obvious. Your comments should be written in plain, standard English (although some people's mind would still die). You should have a description of what your class contains and how to use it.
These are things you would learn in a Software Engineering class, at least.
But I guess there's really no such thing as Software Engineering, hur hur hur...