The std::move()
in the code below issues a runtime warning when compiled in Visual Studio 2013 (with Debug configuration) because it detects that dest
is a nullptr
. However, the source range is empty, so dest
should never be accessed.
The C++ standard may be unclear as to whether this should be allowed?
It states: Requires: result shall not be in the range [first,last).
A nullptr
would seem to satisfy that requirement.
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec;
int* dest = nullptr;
// The range [begin(vec),end(vec)) is empty, so dest should never be accessed.
// However, it results in an assertion warning in VS2013.
std::move(std::begin(vec), std::end(vec), dest);
}
Not only does the Requires: clause need to be satisfied, but everything in the Effects: and Returns: clause needs to be satisfied as well. Let's go through them:
Effects: Copies elements in the range
[first,last)
into the range[result,result + (last - first))
starting fromfirst
and proceeding tolast
.
As first == last
, then the range [result, result + 0)
must be a valid range.
[iterator.requirements.general]/p7 states:
A range
[i,i)
is an empty range; ...Range [i,j)
is valid if and only ifj
is reachable fromi
.
And p6 of the same section states:
An iterator
j
is called reachable from an iteratori
if and only if there is a finite sequence of applications of the expression++i
that makesi == j
.
From these paragraphs I conclude that given:
int* dest = nullptr;
Then [dest, dest)
forms a valid empty range. So the first sentence in the Effects: paragraph looks ok to me:
For each non-negative integer
n < (last - first)
, performs*(result + n) = *(first + n)
.
There are no non-negative integers n < 0
, and so no assignments can be performed. So the second sentence does not prohibit dest == nullptr
.
Returns:
result + (last - first)
.
[expr.add]/p8 specifically allows one to add 0 to any pointer value and the result compares equal to the original pointer value. Therefore dest + 0
is a valid expression equal to nullptr
. No problems with the Returns: clause.
Requires:
result
shall not be in the range[first,last)
.
I see no reasonable way to interpret that dest
would be "in" an empty range.
Complexity: Exactly
last - first
assignments.
This confirms that no assignments can be done.
I can find no statement in the standard that makes this example anything but well-formed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With