Reputation: 283733
According to the C++ Standard, it is mandatory for every implementation to document "implementation-defined behavior":
1.3.11
[defns.impl.defined]
implementation-defined behaviorbehavior, for a well-formed program construct and correct data, that depends on the implementation and that each implementation documents
And reading an invalid pointer value has implementation-defined behavior (see 4.1 Lvalue-to-rvalue conversion [conv.lval]
):
if the object to which the glvalue refers contains an invalid pointer value (3.7.4.2, 3.7.4.3), the behavior is implementation-defined.
(quote from draft n4527, but verbiage that "Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior." has been in 3.7.4.2 Deallocation functions [basic.stc.dynamic.deallocation]
since at least draft n3485)
However, many popular implementations do not define this behavior, and many experts describe this as "undefined behavior" instead.
A likely cause for omission of clear documentation is that, as far as I can determine, evaluation of "invalid pointer values" is missing from the "Index of implementation-defined behavior" which appears in Standard drafts following the appendices.
Is this a defect in the Standard, and are there any open Defect Reports or committee actions taken since C++14 concerning it?
Upvotes: 14
Views: 430
Reputation: 60999
CWG #1438 changed the semantics concerning invalid pointer values:
The current Standard says that any use of an invalid pointer value produces undefined behavior (3.7.4.2 [basic.stc.dynamic.deallocation] paragraph 4). This includes not only dereferencing the pointer but even just fetching its value. The reason for this draconian restriction is that some architectures in the past used dedicated address registers for pointer loads and stores and they could fault if, for example, a segment number in a pointer was not currently mapped.
It is not clear whether such restrictions are necessary with architectures currently in use or reasonably foreseen. This should be investigated to see if the restriction can be loosened to apply only to dereferencing the pointer.
The change in [conv.lval] is the resolution of CWG #616, which essentially adopted the above.
Lifting this from UB to implementation-defined behavior was intentional, so I presume the absence of this paragraph in the Index is an oversight.
Upvotes: 9