JTC1/SC22/WG14
N732
ISO/IEC JTC1/SC22/WG14 N732
The meaning of "implementation-defined"
Clive D.W. Feather
Abstract
========
Discussion at the last meeting showed that there were divergent views
on the meaning of the term "implementation-defined". This paper
examines this matter and proposes changes to resolve the issue.
Discussion
==========
The Standard defines three significant terms (presented here out of
order):
3.11 Implementation-defined behavior
Behavior, for a correct program construct and correct
data, that depends on the characteristics of the
implementation and that each implementation shall document.
3.19 Unspecified behavior
Behavior, for a correct program construct and correct
data, for which this International Standard explicitly
imposes no requirements.
3.18 Undefined behavior
Behavior, upon use of a nonportable or erroneous
program construct, of erroneous data, or of indeterminately
valued objects, for which this International Standard
imposes no requirements. Permissible undefined behavior
ranges from ignoring the situation completely with
unpredictable results,
[...]
First consider the term "unspecified behavior". Most commentators on
the Standard are of the opinion that this has the following
properties:
(1) There are a number of possible courses of actions, or the behavior
is one that generates a result and then has a number of possible
results.
(2) The implementation can make any of the available choices, and can
make different choices at different places or times.
(3) The implementation need not document its choices.
(4) No matter what choice the implementation makes, it cannot affect
anything outside the range of that choice. If a value has to be
chosen, it must be a valid value for that type.
Property number 4 is the interesting one: it is usually taken to mean
that the implementation cannot generate a spurious signal, branch to
a random place in the code, or choose a trap representation. All of
these, of course, are valid "undefined behavior".
This interpretation, and particularly property number 4, is usually
assumed to be what is meant by:
for a correct program construct and correct data
At this point, it should be noted that these words are not perhaps
the best ever written. It has been claimed, in other contexts, that
they mean that the construct must be correct, and if it is not the
implementation is not constrained. Since that interpretation would
make unspecified behavior indistinguishable from undefined behaviour,
I reject it. But the wording should be improved.
Now consider the definition of "implementation-defined behavior".
Clearly, this is similar to unspecified behavior, but carries the
words:
that depends on the characteristics of the
implementation and that each implementation shall document
The most obvious reading is that property 3 above does not apply,
and should be replaced by:
(3A) The implementation must document its choices.
Given the similarities in wording otherwise, I conclude that it was
intended that properties 1, 2, and 4 still apply.
At this point it should be noted that there are really two separate
situations where implementation-defined behavior occurs. In the first
(for example, whether plain char is signed or unsigned), property 4
remains desirable; no matter what choice is made, a program should be
able to safely use the construct. In the second (for example, the
result of left-shifting a negative value), there are implementations
that wish to generate a visible exception or invoke behavior outside
the range of that property. It is the wish to do the latter that has
led to the belief that "implementation-defined behavior can be
undefined behavior provided it's in the manual as such".
Since both these types of "implementation-defined behavior" are of
use within the Standard, we should explicitly have both.
This proposal introduces the term "implementation-limited behavior"
for the second type. Note that programs that contain implementation-
defined (or unspecified) behavior are conforming to all conforming
implementations, though their output will vary, while programs that
contain implementation-limited (or undefined) behavior can only be
run on some subset of conforming implementations.
Proposal
========
Replace 3.19 ("unspecified behavior") with:
3.19 Unspecified behavior
Behavior where this International Standard provides two or
more possibilities and imposes no requirements on which is
chosen in any instance. An otherwise correct program containing
unspecified behaviour shall execute correctly on all
implementations.
Replace 3.11 ("implementation-defined behavior") with:
3.11 Implementation-defined behavior
Unspecified behavior where each implementation shall document
how the choice is made.
Add a new definition:
3.X Implementation-limited behavior
Behavior that depends on the characteristics of the
implementation and that each implementation shall document.
A program that contains implementation-limited behaviour need
not execute correctly on a given implementation.
In clause 4 paragraph 1, change:
It shall not produce output dependent on any unspecified,
undefined, or implementation-defined behaviour ...
to:
It shall not produce output dependent on any unspecified,
undefined, implementation-defined, or implementation-limited
behaviour ...
and in paragraph 4 change:
An implementation shall be accompanied by a document that
defines all implementation-defined characteristics and all
extensions.
to:
An implementation shall be accompanied by a document that
defines all implementation-defined and implementation-limited
characteristics and all extensions.
In 5.1.1.3 paragraph 1, change:
... even if the behavior is also explicitly specified as
undefined or implementation-defined.
to:
... even if the behavior is also explicitly specified as
undefined, implementation-defined, or implementation-limited.
Application
===========
Change the following uses of "implementation-defined" to
"implementation-limited":
- 6.1.3.4 paragraph 10 (character constants)
- 6.1.3.4 paragraph 11 (wide character constants)
- 6.1.3.4 examples 3 and 4 (character constants)
- 6.3.2.3 paragraph 5 (type punning in unions)
- 6.3.4 paragraph 4 (certain pointer casts)
- 6.8.6 paragraph 1 (#pragma)
- 6.8.9 paragraph 1 (pragma operator)
- 7.10 paragraph 4 (semantics of signals)
- 7.12.4.4 paragraph 3 (tmpnam called too often)
- 7.12.6.2 p specifier second use (fscanf())
- 7.12.10.4 paragraph 2 (perror())
- 7.13.4.5 paragraph 2 (system())
- 7.18.2.2 p specifier second use (fwscanf())
- N739 item 9a
Change the following uses of "implementation-defined" to
"implementation-defined or implementation-limited":
- 6.3 paragraph 4 (certain operators in expressions)
Change the following uses of "undefined" to
"implementation-limited":
- N723
- N729