Section: 99 [depr.temporary.buffer] Status: C++17 Submitter: Kazutoshi Satoda Opened: 2011-08-10 Last modified: 2017-07-30
Priority: 3
View all other issues in [depr.temporary.buffer].
View all issues with C++17 status.
Discussion:
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
-2- Returns: A pair containing the buffer's address and capacity (in the units ofn
adjacentT
objects. It is implementation-defined whether over-aligned types are supported (3.11).sizeof(T)
), or a pair of 0 values if no storage can be obtained or ifn <= 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.
(for the return value, a pair
P
) [...] the buffer pointed to byP.first
is large enough to holdP.second
objects of typeT
.P.second
is greater than or equal to 0, and less than or equal tolen
.
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 aboutget_temporary_buffer()
. After reading a quote from TC++PL at
stackoverflow,
I realized that the former is intended.
Such misinterpretation seems common:
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 leastn
adjacent objects of typeT
.
I know one commercial compiler package based on Rogue Wave implementation, and its implementation is essentially same as the above.
[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).
[2015-05, Lenexa]
MC: move to ready? in favor: 14, opposed: 0, abstain: 0
Proposed resolution:
This wording is relative to N3936.
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
-?- Remarks: CallingN
adjacent objects of typeT
, for some non-negative numberN
.Obtains a pointer to storage sufficient to store up toIt is implementation-defined whether over-aligned types are supported (3.11).n
adjacentT
objects.get_temporary_buffer
with a positive numbern
is a non-binding request to return storage forn
objects of typeT
. In this case, an implementation is permitted to return instead storage for a non-negative numberN
of such objects, whereN != n
(includingN == 0
). [Note: The request is non-binding to allow latitude for implementation-specific optimizations of its memory management. — end note]. -2- Returns: Ifn <= 0
or if no storage could be obtained, returns a pairP
such thatP.first
is a null pointer value andP.second == 0
; otherwise returns a pairP
such thatP.first
refers to the address of the uninitialized storage andP.second
refers to its capacityN
(in the units ofsizeof(T)
).Apair
containing the buffer's address and capacity (in the units ofsizeof(T)
), or a pair of 0 values if no storage can be obtained or ifn <= 0
.template <class T> void return_temporary_buffer(T* p);-3- Effects: Deallocates the
-4- Requires:buffer to whichstorage referenced byp
pointsp
.The buffer shall have been previously allocated byp
shall be a pointer value returned by an earlier call toget_temporary_buffer
which has not been invalidated by an intervening call toreturn_temporary_buffer(T*)
. -?- Throws: Nothing.