mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 22:52:01 +00:00
Removed obsolete documentation about duplicate address problems
It no longer applies since instances are now identified by both address and type.
This commit is contained in:
parent
1b05ce5bc0
commit
efc2aa7ee7
@ -627,79 +627,17 @@ functions. The default policy is :enum:`return_value_policy::automatic`.
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
Code with invalid call policies might access unitialized memory or free
|
Code with invalid return value policies might access unitialized memory or
|
||||||
data structures multiple times, which can lead to hard-to-debug
|
free data structures multiple times, which can lead to hard-to-debug
|
||||||
non-determinism and segmentation faults, hence it is worth spending the
|
non-determinism and segmentation faults, hence it is worth spending the
|
||||||
time to understand all the different options in the table above.
|
time to understand all the different options in the table above.
|
||||||
|
|
||||||
One important aspect regarding the above policies is that they only apply to
|
One important aspect of the above policies is that they only apply to instances
|
||||||
instances which pybind11 has *not* seen before, in which case the policy
|
which pybind11 has *not* seen before, in which case the policy clarifies
|
||||||
clarifies essential questions about the return value's lifetime and ownership.
|
essential questions about the return value's lifetime and ownership. When
|
||||||
|
pybind11 knows the instance already (as identified by its type and address in
|
||||||
When pybind11 knows the instance already (as identified via its address in
|
|
||||||
memory), it will return the existing Python object wrapper rather than creating
|
memory), it will return the existing Python object wrapper rather than creating
|
||||||
a copy. This means that functions which merely cast a reference (or pointer)
|
a copy.
|
||||||
into a different type don't do what one would expect:
|
|
||||||
|
|
||||||
.. code-block:: cpp
|
|
||||||
|
|
||||||
A &func(B &value) { return (A&) value; }
|
|
||||||
|
|
||||||
The wrapped version of this function will return the original ``B`` instance.
|
|
||||||
To force a cast, the argument should be returned by value.
|
|
||||||
|
|
||||||
More common (and equally problematic) are cases where methods (e.g. getters)
|
|
||||||
return a pointer or reference to the first attribute of a class.
|
|
||||||
|
|
||||||
.. code-block:: cpp
|
|
||||||
:emphasize-lines: 3, 13
|
|
||||||
|
|
||||||
class Example {
|
|
||||||
public:
|
|
||||||
Internal &get_internal() { return internal; }
|
|
||||||
private:
|
|
||||||
Internal internal;
|
|
||||||
};
|
|
||||||
|
|
||||||
PYBIND11_PLUGIN(example) {
|
|
||||||
py::module m("example", "pybind11 example plugin");
|
|
||||||
|
|
||||||
py::class_<Example>(m, "Example")
|
|
||||||
.def(py::init<>())
|
|
||||||
.def("get_internal", &Example::get_internal); /* Note: don't do this! */
|
|
||||||
|
|
||||||
return m.ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
As in the above casting example, the instance and its attribute will be located
|
|
||||||
at the same address in memory, which pybind11 will recongnize and return the
|
|
||||||
parent instance instead of creating a new Python object that represents the
|
|
||||||
attribute. The special :enum:`return_value_policy::reference_internal` policy
|
|
||||||
should be used in this case: it disables the same-address optimization and
|
|
||||||
ensures that pybind11 returns a reference.
|
|
||||||
The following example snippet shows the correct usage:
|
|
||||||
|
|
||||||
.. code-block:: cpp
|
|
||||||
|
|
||||||
class Example {
|
|
||||||
public:
|
|
||||||
Internal &get_internal() { return internal; }
|
|
||||||
private:
|
|
||||||
Internal internal;
|
|
||||||
};
|
|
||||||
|
|
||||||
PYBIND11_PLUGIN(example) {
|
|
||||||
py::module m("example", "pybind11 example plugin");
|
|
||||||
|
|
||||||
py::class_<Example>(m, "Example")
|
|
||||||
.def(py::init<>())
|
|
||||||
.def("get_internal", &Example::get_internal, "Return the internal data",
|
|
||||||
py::return_value_policy::reference_internal);
|
|
||||||
|
|
||||||
return m.ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user