I call this "drive-by" commenting, and I do this so that others don't have to waste their time figuring out the things that I did. I find it particularly important to surface assumptions a piece of code may make, that aren't obvious from its signature. Random recent examples:
- A C++ function that takes two containers and internally does std::transform on them: hidden assumption here is the second container is at least as big as the first one (otherwise std::transform will try to read past its end).
- A C++ function that internally calls std::unique and std::sort: the inputs now must be valid for comparison under == and <, and also the output is now sorted - which may, or may not, be something some users already rely on. Better to either pin this behavior down in documentation, or explicitly disclaim it ("relative order of input elements is not preserved") to leave some wiggle room for future changes.
A lot of such things can be expressed using type systems, compile-time checks and runtime checks, but it's not always obvious to the reader. My approach is: if a function makes an assumption or guarantee in a way you won't see it in its signature, and your IDE won't pick up on it automatically, then it should be described in the comment.
Some such things can also be pinned down in unit tests, to better protect against inadvertent breakage due to refactorings - but I say also, not instead, because day-to-day, nobody actually looks at unit tests related to random functions they call, while a properly configured editor or IDE will show documentation comments of function signatures as you type or browse completions.