Since there's confusion on conformance semantics, these are the rules for C++. C uses a completely different conformance model.
Undefined behaviour is an oxymoronic term, it means the translator NOT your program, may do as it pleases. This generally means it can generate code which will also do anything it pleases (but that is a deduction). Where the Standard says behaviour is undefined the text is actually of no significance to the user in the sense that eliding this text will not change the requirements the Standard imposes on translators.
Ill formed program means that unless otherwise specified the behaviour of the translator is rigidly defined: it is required to reject your program and issue a diagnostic message.
The primary special case here is the One-Definition Rule, if you breach that your program is ill-formed but no diagnostic is required.
Implementation defined imposes a requirement on the translator that it contain documentation specifying the behaviour explicitly. In this special case Undefined Behaviour can be the result but must be explicitly stated.
Unspecified is a stupid term which means that the behaviour come from a set. In this sense well-defined is just a special case where the set of permitted behaviours contains only one element. Unspecified does not require documentation, so in some sense it also means the same as implementation defined without documentation.
In general, the C++ Standard is a not a Language Standard, it is a model for a language Standard. To generate an actual Standard you have to plug in various parameters. The easiest of these to recognize are the implementation defined limits.
There are a couple of silly conflicts in the Standard, for example, a legitimate translator can reject every apparently good C++ program on the basis that you are required to supply a main()
function but the translator only supports identifiers of 1 character. This problem is resolve by the notion of QOI or Quality of Implementation. It basically says, who cares, no one is going to buy that compiler just because it is conforming.
Technically the unspecified nature of operator <
when the pointers are to unrelated objects is probably intended to mean: you will get some kind of result which is either true or false but your program will not crash, however this is not the correct meaning of unspecified, so that is a Defect: unspecified imposed a burden on the Standards writers to document the set of allowed behaviours because if the set is open, then it is equivalent to undefined behaviour.
I actually proposed std::less
as a solution to the problem that some data structures require keys to be totally ordered, but pointers are not totally ordered by operator <
. On most machines using linear addressing less
is the same as <
, but the less
operation on, say, an x86 processor is potentially more expensive.
if (this != &other)
– Syzran==
must only be true if both of them are null pointers, or else refer to the same object (and the converse for!=
, of course). – Alvita