Comments can sometimes be a code smell. People often use comments to explain how their code works. Instead of making their code more readable they just add comments to explain it. If this is the case they should refactor to have their code express itself so there is no need for comments.
Comments are still fine in many instances. The main problem comes when people try to use them to explain their code, more specifically how they implemented something. According to Martin Fowler, comments that explain why you choose to implement a piece of code a certain way are fine. This is because it is hard to express implementation decisions in the code.
It is important to only have comments that are necessary. This is because comments need to be maintained. According to Michael Toppa, comments are often lies waiting to happen. In his experience people often forget to maintain comments.
To make the code express itself better, you can extract methods out of the code and use more meaningful names. Adding assertions also helps code express itself better.