Avoid exposing move semantics to the external Python API to preclude undefined behaviour
Consider a C++ class DataSet
with the following constructor:
DataSet::DataSet(std::shared_ptr<IDataReader> reader)
: _reader{std::move(reader)}
{
// do something...
}
Exposing this constructor to the Python API leads to unknown/undefined behaviour:
import pynsx as nsx
expr = nsx.Experiment('test', 'BioDiff2500')
diffractometer = expr.diffractometer()
reader = nsx.HDF5DataReader("datafile.nsx", diffractometer)
data = nsx.DataSet(reader)
reader.someMethod() # unknown behaviour since `reader` is moved!
reader.someVariable # unknown result since `reader` is moved!
NOTE: cppreference for std::move states that
Unless otherwise specified, all standard library objects that have been moved from are placed in a "valid but unspecified state".
Edited by Ammar Nejati