-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Is your feature request related to a problem? Please describe.
Currently stack allocated C++ classes and temps require default constructors since they're initialized at the start of the function.
cdef extern from *:
cdef cppclass Someclass:
pass
SomeClass func() except +
def f(make_someclass: bool):
if make_someclass:
a = func()
this generates code along the lines of:
PyObject* f(...) {
Someclass a
Someclass __pyx_t_1;
if (make_someclass) {
try {
__pyx_t_1 = make_someclass();
} catch (...) {
// exception handling here
}
a = __PYX_MOVE_IF_POSSIBLE(__pyx_t_1);
}
}
This puts restrictions on what c++ types can be used on the stack (or even as return types of functions, because of the temps creates)
Describe the solution you'd like
std::optional provides a way around this. It'd be possible to create the stack variables as:
std::optional<Someclass> a;
std::optional<Someclass> __pyx_t_1;
These keep keep track of whether it's been assigned, and handle destruction etc. as needed.
My proposal is that this should be an opt-in feature, controlled by a directive. There's a number of good reasons not to do it by default:
- C++17 only (which is a fairly hefty requirement)
- Potential performance changes (due to extra space usage, and "initialized tests"
- Changes in Cython behaviour - accessing an uninitialized C++ variable becomes a potential crash rather than an access to a valid default-initialized object.
I think the Cython type system would have to know about the std::optional and treat them as a slightly different type to the raw classes - *optional gets to the underlying class, which is a trivial coercion, but one that can't happen automatically.
Describe alternatives you've considered
The status quo.
Reimplement std::optional (i.e. it's a library feature, I don't think it requires a significant compiler support). That would reduce the compiler requirement, but require more effort. It could also be implemented in terms of std::optional first then revisited if need.
Additional context
Exceptions from constructors/operators are a potential problem. But equally exceptions from default/copy/move constructors/operators are an issue in Cython currently.