Comments can be written at any stage, comments SHOULD be written when you believe the code needs explanation and you know that you understand it.
Believing the code needs explanation should almost always be based upon your belief about how easy it is to understand the purpose of the code -- if the purpose is clear, then you probably don't need an explanation as to what it is doing. This is in part the purpose of good naming -- so that given a name of a function and it's input/output, you will understand why the code is needed and why it is doing whatever it is doing.
Comments on the syntax should be extremely rare, pretty much limited to cases where it is BOTH obscure AND possible to misunderstand it to be something else. If it's simply obscure, then trust that they will look it up if they need it, if it's simply likely to be misunderstood a + b * c
then write it so that it's less likely to misunderstand a + (b*c)
. If on the other hand the purpose is unclear (working around a framework/compiler bug for an extreme example) then you need a comment so that the next person can understand why you are doing what you are doing.
Adding comments when you debug is fine, debugging naturally brings you back to older code which you may struggle to understand -- and struggling to understand, you know that it needs comments.
This may be why lots of people start off giving comments on syntax -- they haven't yet mastered it, and are still struggling with it a bit, and don't have enough experience to realize that syntax is something that they will learn and understand later. They expect to have trouble understanding the syntax, and thus provide a comment.
But having this as your normal mode of operation is not ideal, at best it is then helpful the 2nd time you have to debug that code. You should strive to anticipate where you will have trouble understanding the code, and write the comments explaining it as it is written. Don't expect to get it right all the time, or even most of the time at first. Just try to do better.