I think this is somewhat misleading. It's easy to give a semantics for a toy C-like imperative language. As far as I know, a semantics that is mostly faithful to the C standard becomes extremely complicated and requires modeling e.g. code layout in memory. The equational reasoning you get from that kind of semantics is terribly weak: essentially, only terms that have the same byte-for-byte effect on memory are really equivalent. So I wouldn't say that exploiting "referential transparency" in Haskell is somehow more obvious, but that it's useful at all.