The following remarks are based on the C standard, ISO-9899, rather than the C++ one, but the meanings are fundamentally the same (see sections 3.4 and 4 of the C standard; see also the C++ standard, ISO-14882, section 1.3; the latter document doesn't define 'unspecified value' as such, but does use that phrase later with the obvious meaning). The official standards documents are not free (indeed, they are expensive), but the links above are to the committee pages, and include free 'drafts' of the standard, which you can take to be essentially equivalent to the finalised standard text.

The terms describe a ladder of vagueness.

So, heading downwards....

Most of the time, the standard defines what should happen in a particular case: if you write c=a+b and a and b are int , then c is their sum (modulo some details). This, of course, is the point of a standard.

Implementation-defined behaviour is where the standard lists two or more things which are allowed to happen in a particular case; it doesn't prescribe which one is preferred, but does demand that the implementation (the actual compiler which parses the C) makes a choice between the alternatives, does that same thing consistently, and that the implementation must document the choice it makes. For example, whether a single file can be opened by multiple processes is implementation-defined.

Unspecified behaviour is where the standard lists a couple of alternatives, each of which is therefore conformant with the standard, but goes no further. An implementation must choose one of the alternatives to pick in a particular case, but doesn't have to do the same thing each time, and doesn't have to commit itself in documentation to which choice it will make. For example, the padding bits in a struct are unspecified.

Undefined behaviour is the most extreme case. Here, all bets are off. If the compiler, or the program it generates, runs into undefined behaviour, it can do anything: it can scramble memory, corrupt the stack, HCF or, in the standard extreme case, cause demons to fly out of your nose. But mostly it'll just crash. And all of these behaviours are conformant with the standard. For example, if a variable is declared both static int i; and int i; in the same scope, or if you write #include <'my file'.h> , the effect is undefined.

There are analogous definitions for 'value'.

An unspecified value is a valid value, but the standard doesn't say what it is. Thus the standard might say that a given function returns an unspecified value. You can store that value and look at it if you want to, without causing an error, but it doesn't mean anything, and the function might return a different value next time, depending on the phase of the moon.

An implementation-defined value is like implementation-defined behaviour. Like unspecified, it's a valid value, but the implementation's documentation has to commit itself on what will be returned, and do the same thing each time.

An indeterminate value even more unspecified than unspecified. It's either an unspecified value or a trap representation. A trap representation is standards-speak for some magic value which, if you try to assign it to anything, results in undefined behaviour. This wouldn't have to be an actual value; probably the best way to think about it is "if C had exceptions, a trap representation would be an exception". For example, if you declare int i; in a block, without an initialisation, the initial value of the variable i is indeterminate, meaning that if you try to assign this to something else before initialising it, the behaviour is undefined, and the compiler is entitled to try the said demons-out-of-nose trick. Of course, in most cases, the compiler will do something less dramatic/fun, like initialise it to 0 or some other random valid value, but no matter what it does, you're not entitled to object.

The point of all this imprecision is to give maximal freedom to compiler writers. That's nice for compiler writers (and is one of the reasons it's reasonably easy to get a C compiler running on such a huge range of platforms), but it does make things rather more interesting than fun for the poor users.

Edit 1: to clarify indeterminate values.

Edit 2: to include a link to the C++ standard, and note that the committee drafts are essentially equivalent to the final standard, but free.