Nearly all programming languages used are Turing Complete, and while this affords the language to represent any computable algorithm, it also comes with its own set of probl
BlooP (short for Bounded loop) is an interesting non-Turing-complete language. It's a essentially a Turing-complete language, with one (major) caveat: every loop must contain a bound on the number of iterations. Infinite loops are not allowed. As a result, the Halting Problem can be solved for BlooP programs.
The right way to do this, IMHO, is to have a language which is Turing complete, but to provide a system for stating semantics amenable to processing by a proof checker.
Then, assuming you are writing a terminating program deliberately, you have in you mind a good argument as to why it halts, and with this new kind of language you should be able to express that argument, and have it proven.
As an aside in my production compiler I have recursions which I know, for sure, will NOT halt on certain inputs .. I use a nasty hack to stop this: a counter with a "sensible" limit. FYI the actual code is involve in monomorphising polymorphic code, and the infinite expansion occurs when using polymorphic recursion. Haskell catches this, my compiler for Felix doesn't (that's a bug in the compiler I happen not to know how to fix).
Following from my general argument .. I'd sure like to know what kinds of annotations would be good for the stated purpose: I happen to have control of a language and compiler so I could easily add such support if only I knew exactly what to add :) I have seen the addition of an "invariant" and "variant" clause to loops for this purpose, although I don't think the language extended to using that information for proof of termination (rather it checked the invariant and variant at run time if I remember correctly).
Maybe that deserves another question ..