This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-11-11


1910. “Shall” requirement applied to runtime behavior

Section: 6.7.5.5.2  [basic.stc.dynamic.allocation]     Status: CD5     Submitter: Richard Smith     Date: 2014-04-12

[Accepted as a DR at the March, 2018 (Jacksonville) meeting.]

According to 6.7.5.5.2 [basic.stc.dynamic.allocation] paragraph 3,

If an allocation function declared with a non-throwing exception-specification (14.5 [except.spec]) fails to allocate storage, it shall return a null pointer. Any other allocation function that fails to allocate storage shall indicate failure only by throwing an exception (14.2 [except.throw]) of a type that would match a handler (14.4 [except.handle]) of type std::bad_alloc (17.6.4.1 [bad.alloc]).

The use of the word “shall” to constrain runtime behavior is inappropriate, as it normally identifies cases requiring a compile-time diagnostic.

Proposed resolution (November, 2017)

  1. Change 6.7.5.5 [basic.stc.dynamic] paragraph 3 as follows:

  2. Any allocation and/or deallocation functions defined in a C ++ program, including the default versions in the library, shall conform to the semantics If the behavior of an allocation or deallocation function does not satisfy the semantic constraints specified in 6.7.5.5.2 [basic.stc.dynamic.allocation] and 6.7.5.5.3 [basic.stc.dynamic.deallocation], the behavior is undefined.
  3. Change 6.7.5.5.2 [basic.stc.dynamic.allocation] paragraph 1 as follows:

  4. ...The value of the first parameter shall be is interpreted as the requested size of the allocation...
  5. Change 6.7.5.5.2 [basic.stc.dynamic.allocation] paragraph 2 as follows:

  6. The An allocation function attempts to allocate the requested amount of storage. If it is successful, it shall return returns the address of the start of a block of storage whose length in bytes shall be is at least as large as the requested size. There are no constraints on the contents of the allocated storage on return from the allocation function. The order, contiguity, and initial value of storage allocated by successive calls to an allocation function are unspecified. The For an allocation function other than a reserved placement allocation function (17.6.3.4 [new.delete.placement], the pointer returned shall be is suitably aligned so that it can be converted to a pointer to any suitable complete object type (17.6.3.2 [new.delete.single]) and then used to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to a corresponding deallocation function). Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be by a replaceable allocation function is a non-null pointer value (7.3.12 [conv.ptr]) p0 different from any previously returned value p1, unless that value p1 was subsequently passed to an operator delete a replaceable deallocation function. Furthermore, for the library allocation functions in 17.6.3.2 [new.delete.single] and 17.6.3.3 [new.delete.array], p0 shall represent represents the address of a block of storage disjoint from the storage for any other object accessible to the caller. The effect of indirecting through a pointer returned as from a request for zero size is undefined.38
  7. Change 6.7.5.5.2 [basic.stc.dynamic.allocation] paragraph 3 as follows:

  8. An allocation function that fails to allocate storage can invoke the currently installed new-handler function (17.6.4.3 [new.handler]), if any. [Note: A program-supplied allocation function can obtain the address of the currently installed new_handler using the std::get_new_handler function (17.6.4.4 [set.new.handler]). —end note] If an An allocation function that has a non-throwing exception specification (14.5 [except.spec]) fails to allocate storage, it shall return indicates failure by returning a null pointer value. Any other allocation function that fails to allocate storage shall indicate never returns a null pointer value and indicates failure only by throwing an exception (14.2 [except.throw]) of a type that would match a handler (14.4 [except.handle]) of type std::bad_alloc (17.6.4.1 [bad.alloc]).