4 General principles [intro]

4.1 Implementation compliance [intro.compliance]

The set of diagnosable rules consists of all syntactic and semantic rules in this document except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior”.
Although this document states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs.
Such requirements have the following meaning:
  • If a program contains no violations of the rules in this document, a conforming implementation shall, within its resource limits, accept and correctly execute2 that program.
  • If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
  • If a program contains a violation of a rule for which no diagnostic is required, this document places no requirement on implementations with respect to that program.
During template argument deduction and substitution, certain constructs that in other contexts require a diagnostic are treated differently; see [temp.deduct].
end note
For classes and class templates, the library Clauses specify partial definitions.
Private members are not specified, but each implementation shall supply them to complete the definitions according to the description in the library Clauses.
For functions, function templates, objects, and values, the library Clauses specify declarations.
Implementations shall supply definitions consistent with the descriptions in the library Clauses.
The names defined in the library have namespace scope ([basic.namespace]).
A C++ translation unit obtains access to these names by including the appropriate standard library header.
The templates, classes, functions, and objects in the library have external linkage.
The implementation provides definitions for standard library entities, as necessary, while combining translation units to form a complete C++ program ([lex.phases]).
Two kinds of implementations are defined: a hosted implementation and a freestanding implementation.
For a hosted implementation, this document defines the set of available libraries.
A freestanding implementation is one in which execution may take place without the benefit of an operating system, and has an implementation-defined set of libraries that includes certain language-support libraries ([compliance]).
A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program.
Implementations are required to diagnose programs that use such extensions that are ill-formed according to this document.
Having done so, however, they can compile and execute such programs.
Each implementation shall include documentation that identifies all conditionally-supported constructs that it does not support and defines all locale-specific characteristics.3
“Correct execution” can include undefined behavior, depending on the data being processed; see [intro.defs] and [intro.execution].
This documentation also defines implementation-defined behavior; see [intro.execution].

4.1.1 Abstract machine [intro.abstract]

The semantic descriptions in this document define a parameterized nondeterministic abstract machine.
This document places no requirement on the structure of conforming implementations.
In particular, they need not copy or emulate the structure of the abstract machine.
Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.4
Certain aspects and operations of the abstract machine are described in this document as implementation-defined (for example, sizeof(int)).
These constitute the parameters of the abstract machine.
Each implementation shall include documentation describing its characteristics and behavior in these respects.5
Such documentation shall define the instance of the abstract machine that corresponds to that implementation (referred to as the “corresponding instance” below).
Certain other aspects and operations of the abstract machine are described in this document as unspecified (for example, evaluation of expressions in a new-initializer if the allocation function fails to allocate memory ([expr.new])).
Where possible, this document defines a set of allowable behaviors.
These define the nondeterministic aspects of the abstract machine.
An instance of the abstract machine can thus have more than one possible execution for a given program and a given input.
Certain other operations are described in this document as undefined (for example, the effect of attempting to modify a const object).
This document imposes no requirements on the behavior of programs that contain undefined behavior.
end note
A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input.
However, if any such execution contains an undefined operation, this document places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).
The least requirements on a conforming implementation are:
  • Accesses through volatile glvalues are evaluated strictly according to the rules of the abstract machine.
  • At program termination, all data written into files shall be identical to one of the possible results that execution of the program according to the abstract semantics would have produced.
  • The input and output dynamics of interactive devices shall take place in such a fashion that prompting output is actually delivered before a program waits for input.
    What constitutes an interactive device is implementation-defined.
These collectively are referred to as the observable behavior of the program.
More stringent correspondences between abstract and actual semantics may be defined by each implementation.
end note
Operators can be regrouped according to the usual mathematical rules only where the operators really are associative or commutative.6
For example, in the following fragment
int a, b;
/* ... */
a = a + 32760 + b + 5;
the expression statement behaves exactly the same as
a = (((a + 32760) + b) + 5);
due to the associativity and precedence of these operators.
Thus, the result of the sum (a + 32760) is next added to b, and that result is then added to 5 which results in the value assigned to a.
On a machine in which overflows produce an exception and in which the range of values representable by an int is [-32768, +32767], the implementation cannot rewrite this expression as
a = ((a + b) + 32765);
since if the values for a and b were, respectively, -32754 and -15, the sum a + b would produce an exception while the original expression would not; nor can the expression be rewritten either as
a = ((a + 32765) + b);
a = (a + (b + 32765));
since the values for a and b might have been, respectively, 4 and -8 or -17 and 12.
However on a machine in which overflows do not produce an exception and in which the results of overflows are reversible, the above expression statement can be rewritten by the implementation in any of the above ways because the same result will occur.
end note
This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this document as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.
For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.
This documentation also includes conditionally-supported constructs and locale-specific behavior.
Overloaded operators are never assumed to be associative or commutative.