godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.74k stars 575 forks source link

When register a Abstract Class using GDREGISTER_CLASS(), compiled without error #1425

Closed pupil1337 closed 6 months ago

pupil1337 commented 7 months ago

Godot version

4.3.dev(29b3d9e)

godot-cpp version

4.3.dev(a62f633)

System information

windows 11

Issue description

Created an Abstract class that inherits from Node. When I registered this class using GDREGISTER_CLASS() in register_types.cpp and compiled the project, the C++ did not report any errors.

Open the engine, and selecte this class to create a root node, it will print error: QQ截图20240329171501

The expected result is that when I register an abstract class with GDREGISTER_CLASS(), the project cannot be compiled.

I analyzed and it seems that the following code caused the class constructor to be skipped during compilation:

// class_db.hpp
template <class T>
static GDExtensionObjectPtr _create_instance_func(void *data) {
    if constexpr (!std::is_abstract_v<T>) {
        T *new_object = memnew(T);
        return new_object->_owner;
    } else {
        return nullptr; // <- will execute this line
    }
}

Steps to reproduce

class Foo : public Node {
  GDCLASS(Foo, Node)

  virtual void func() = 0;
};

Minimal reproduction project

N/A

pupil1337 commented 7 months ago

When my class A inherits an abstract class X, my goal was to implement pure virtual methods. When forget implement pure virtual methods, because _create_instance_func hide the memnew, led to skip create instance, So there is no compilation error to prompt me, but usually new A() has an error prompt like "Allocating an object of abstract class".