Skip to content

Commit 989a764

Browse files
committed
Add DISABLE_OBJECT_BINDING_GUARD compiler flag
The guard in `Wrapped::Wrapped(const StringName)` detects the partial initialization of `godot::Object` subclasses. This is needed because using `new` to allocate a `godot::Object` subclass will result in unexpected crashes because the bindings for the instance have not been set. The side effect of this guard is that it also prevents any use of a `godot::Object` subclass on the stack. There are godot native types such as `godot::RegEx` that are safe to use on the stack, and are used that way throughout the godot source. Similarly, custom classes that subclass `godot::Object` may also be used safely on the stack[^1]. In this commit, I add a compiler flag to disable this guard. This will allow godot-cpp users who understand the safety implications to use `godot::Object` subclasses on the stack. [^1]: godotengine#1446 (comment)
1 parent fbbf9ec commit 989a764

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

src/classes/wrapped.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,24 @@ Wrapped::Wrapped(const StringName p_godot_class) {
8484
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _constructing_class_binding_callbacks);
8585
_constructing_class_binding_callbacks = nullptr;
8686
} else {
87+
#ifndef DISABLE_OBJECT_BINDING_GUARD
88+
// Detect attempts to use godot::Object subclasses without initializing
89+
// the bindings using `memnew`. Failing to initialize the bindings can
90+
// cause unexpected crashes. This guard is in place so new users of
91+
// godot-cpp are warned of this issue and directed to use `memnew`.
92+
//
93+
// The side-effect of this guard is that it prevents the use of
94+
// godot::Object subclasses on the stack. There are godot native
95+
// classes such as godot::RegEx that can be used safely on the stack.
96+
// Custom subclasses of godot::Object may also operate safely without
97+
// the bindings being initialized. To support these cases, use the
98+
// above compiler flag to disable this guard.
99+
//
100+
// If you disable this guard, be aware that any godot::Object subclass
101+
// passed into the godot engine will likely cause a crash unless you
102+
// initialize the bindings using `memnew()`.
87103
CRASH_NOW_MSG("BUG: Godot Object created without binding callbacks. Did you forget to use memnew()?");
104+
#endif
88105
}
89106
}
90107

0 commit comments

Comments
 (0)