GameDevTecnico / cubos

A still very barebones game engine focused on voxels and data-oriented programming
https://gamedevtecnico.github.io/cubos/
MIT License
83 stars 23 forks source link

Find a solution to the undefined reflection errors #1163

Closed RiscadoA closed 1 month ago

RiscadoA commented 4 months ago

Problem

In the 0.2 release, we introduced the ability to automatically define reflections for types without them, instead of failing. This means that calls to reflect<T> when T has no reflection no longer fail. Instead, they return a generated unnamed type. The main problem with this is that this leads to undefined behavior when the user forgets to include a file which defines reflection for an external type.

For example:

// a.cpp
#include <cubos/core/reflection/external/primitives.hpp>

void test1()
{
  std::cout << reflect<int>().name();
}

// b.cpp
void test2()
{
  std::cout << reflect<int>().name();
}

In this example, it would be expected that a call to test2 would print unnamed3280423897492 or something like that, and test print int. But, in reality, this isn't guaranteed. In fact, test1 might even print the unnamed variant. This happens because usually the linker only produces one version of each function. There won't be two different reflect<int> functions. Then its basically a data race between the two versions, and there isn't a guarantee on which one will be picked.

This is extremely confusing to debug, as the errors may pop up anywhere in the code base, instead of where the user forgot to include a header. Thus, we should find an alternative solution to allow us to have types without reflection, or simply revert back to forcing reflection.