TL;DR: Does the __block attribute on an std::vector prevent RVO in Objective-C++? 
In Modern C++, the canonical way to return a vector from a function is to just return it by value so that return value optimization can be used if possible. In Objective-C++, this appears to work the same way.
- (void)fetchPeople {
  std::vector<Person> people = [self readPeopleFromDatabase];
}
- (std::vector<Person>)readPeopleFromDatabase {
  std::vector<Person> people;
  people.emplace_back(...);
  people.emplace_back(...);
  // No copy is made here.
  return people;
}
However, if the __block attribute is applied to the second vector, then it appears that a copy of the vector is being created when it returns. Here is a slightly contrived example: 
- (std::vector<Person>)readPeopleFromDatabase {
  // __block is needed to allow the vector to be modified.
  __block std::vector<Person> people;
  void (^block)() = ^ {
    people.emplace_back(...);
    people.emplace_back(...);
  };
  block();
  #if 1
  // This appears to require a copy.
  return people;
  #else
  // This does not require a copy.
  return std::move(people);
  #endif
}
There are plenty of Stack Overflow questions that explicitly state that you don't need to use std::move when returning a vector because that will prevent copy elision from taking place. 
However, this Stack Overflow question states that there are, indeed, some times when you do need to explicitly use std::move when copy elision is not possible. 
Is the use of __block in Objective-C++ one of those times when copy elision is not possible and std::move should be used instead? My profiling appears to confirm that, but I'd love a more authoritative explanation. 
(This is on Xcode 10 with C++17 support.)
 
    