Title
Unclear wording about capacity of temporary buffers
Status
c++17
Section
[depr.temporary.buffer]
Submitter
Kazutoshi Satoda

Created on 2011-08-10.00:00:00 last changed 90 months ago

Messages

Date: 2015-05-07.20:33:29

Proposed resolution:

This wording is relative to N3936.

  1. Change [temporary.buffer] as indicated:

    template <class T>
      pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
    

    -1- Effects: Obtains a pointer to uninitialized, contiguous storage for N adjacent objects of type T, for some non-negative number N.Obtains a pointer to storage sufficient to store up to n adjacent T objects. It is implementation-defined whether over-aligned types are supported (3.11).

    -?- Remarks: Calling get_temporary_buffer with a positive number n is a non-binding request to return storage for n objects of type T. In this case, an implementation is permitted to return instead storage for a non-negative number N of such objects, where N != n (including N == 0). [Note: The request is non-binding to allow latitude for implementation-specific optimizations of its memory management. — end note].

    -2- Returns: If n <= 0 or if no storage could be obtained, returns a pair P such that P.first is a null pointer value and P.second == 0; otherwise returns a pair P such that P.first refers to the address of the uninitialized storage and P.second refers to its capacity N (in the units of sizeof(T)).A pair containing the buffer's address and capacity (in the units of sizeof(T)), or a pair of 0 values if no storage can be obtained or if n <= 0.

    template <class T> void return_temporary_buffer(T* p);
    

    -3- Effects: Deallocates the buffer to which p pointsstorage referenced by p.

    -4- Requires: The buffer shall have been previously allocated byp shall be a pointer value returned by an earlier call to get_temporary_buffer which has not been invalidated by an intervening call to return_temporary_buffer(T*).

    -?- Throws: Nothing.

Date: 2015-05-07.20:33:29

[ 2015-05, Lenexa ]

MC: move to ready? in favor: 14, opposed: 0, abstain: 0

Date: 2014-05-15.00:00:00

[ 2014-05-18, Daniel comments and suggests concrete wording ]

The provided wording attempts to clarify the discussed capacity freedom, but it also makes it clearer that the returned memory is just "raw memory", which is currently not really clear. In addition the wording clarifies that the deallocating return_temporary_buffer function does not throw exceptions, which I believe is the intention when the preconditions of the functions are satisfied. Then, my understanding is that we can provide to return_temporary_buffer a null pointer value if that was the value, get_temporary_buffer() had returned. Furthermore, as STL noticed, the current wording seemingly allows multiple invocations of return_temporary_buffer with the same value returned by get_temporary_buffer; this should be constrained similar to the wording we have for operator delete (unfortunately we miss such wording for allocators).

Date: 2011-08-10.00:00:00

According to [temporary.buffer] p1+2:

template <class T>
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;

-1- Effects: Obtains a pointer to storage sufficient to store up to n adjacent T objects. It is implementation-defined whether over-aligned types are supported (3.11).

-2- Returns: A pair containing the buffer's address and capacity (in the units of sizeof(T)), or a pair of 0 values if no storage can be obtained or if n <= 0.

I read this as prohibiting to return a buffer of which capacity is less than n, because such a buffer is not sufficient to store n objects.

The corresponding description in SGI STL is clear on this point, but I think it is a bit too verbose:

(for the return value, a pair P) [...] the buffer pointed to by P.first is large enough to hold P.second objects of type T. P.second is greater than or equal to 0, and less than or equal to len.

There seems to be two different targets of the "up to n" modification: The capacity of obtained buffer, and the actual number that the caller will store into the buffer.

First I read as the latter, and got surprised seeing that libstdc++ implementation can return a smaller buffer. I started searching about get_temporary_buffer(). After reading a quote from TC++PL at stackoverflow, I realized that the former is intended.

Such misinterpretation seems common:

  • The above question is likely started from same misinterpretation.
  • JIS standard (Japanese translation of ISO/IEC standard) says nothing like "up to". I think the editor misinterpreted the original wording, and omitted words for "up to" as it is redundant. (If a buffer is sufficient to store n objects, it is also sufficient to store up to n objects.)

  • Rogue Wave implementation doesn't return smaller buffer, instead, it can return larger buffer on some circumstances. Apache STDCXX is a derived version of that implementation, and publicly accessible:

    Specializations of the get_temporary_buffer() function template attempt to allocate a region of storage sufficiently large to store at least n adjacent objects of type T.

    I know one commercial compiler package based on Rogue Wave implementation, and its implementation is essentially same as the above.

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2015-10-27 16:52:45adminsetstatus: ready -> wp
2015-05-07 20:33:29adminsetmessages: + msg7374
2015-05-07 20:33:29adminsetstatus: open -> ready
2014-05-18 16:15:33adminsetmessages: + msg6951
2014-05-18 16:15:33adminsetmessages: + msg6950
2012-02-12 18:36:43adminsetstatus: new -> open
2011-08-10 00:00:00admincreate