Bumping this thread because Raymond Chen wrote a blog post about it. In short: undefined behavior is a runtime concept, where an ill-formed program is a program that breaks one of the rules for how programs are written.
The difference between undefined behavior and ill-formed C++ programs