Because `for` returns (evaluates to) a lazy sequence which means it will only realize individual elements as they are consumed - this is a rough approximation but is more or less what clojure's laziness is about. One of the reasons for laziness is exactly that the entire (potentially infinite) sequence won't have to be realized so operations producing a lazy seq (like for) can return quickly.
So the value of cnt' is a lazy seq. When you print it, the printer sees that it's a sequence so it iterates its elements, which will cause them to be realized, triggering the side effects in the code that realizes the elements.
vec produces a vector which is not lazy so it will need all the elements in cnt', also causing them to be realized. doall is specifically for the purposes of realizing all elements.
To answer the question "why does not clojure wait for cnt' to evaluate" - it does wait for it, but as I wrote above, cnt' evaluates to a lazy seq, which doesn't guarantee that any of its elements are realized yet.
I consider lazy effects a bad practice
https://stuartsierra.com/2015/08/25/clojure-donts-lazy-effects