The ability to redefine the ++ operator would not alone make it difficult to add proper semantics to the C language. What is preventing that is that no one can really describe how function application truly works in C (in terms of operation ordering), except that we all have an idea similar enough that our systems seem to work together in practice.
For all the criticism Haskell gets over the purported difficulty on describing sequential computation, at least the order of monadic operations is clearly captured by the requirements to be a monad. There is no such concept for C, except that each compiler mostly seems to perform operations sequentially.
At least some of it is defined. Annex C of the C99 standard defines when sequence points occur (commonly the ';' operator, but also in a few other places).
Edit: I think a better advantage of Haskell is that Haskell is much more free to not define sequence points. Haskell effectively defaults to not sequencing expressions unless you use a monad or there is some obvious dependency between those expressions like the output of one function used as the input to another.
All that implicit parallelism is something that C compilers have to work hard to derive, but in Haskell it's explicit in the source.
Monad's are not such basic building blocks. It's not monads that define sequencing points. It's that data flow in Haskell is the only way to define control flow. (And Monads make use of that.)
For all the criticism Haskell gets over the purported difficulty on describing sequential computation, at least the order of monadic operations is clearly captured by the requirements to be a monad. There is no such concept for C, except that each compiler mostly seems to perform operations sequentially.