sol2
sol2 copied to clipboard
usertypes: automatically detected to_string can cause crashes
Description: if the tostring function is automatically detected, the program crashes if the usertype is printed.
Workarounds:
- delete the usertype name from the global namespace (haven't run into problems with that in my tests yet)
- manually define the tostring method and don't define to_string or operator<< or disable the autmatic detection
Error:
sol: runtime error: stack index 1, expected userdata, received table: value is not a valid userdata
Other Info:
- Windows (10.0.19042)
- C++ ( /std:c++latest)
- Visual Studio 16.10.0
- cl Version 19.29.30037
Minimal Example:
#include <sol/sol.hpp>
struct TestStruct {
std::string to_string() const { return "to_string"; }
};
int main() {
sol::state s;
s.open_libraries(sol::lib::base);
s.new_usertype<TestStruct>("__TEST");
s.script("print( __TEST)");
return 0;
}
Example:
#include <sol/sol.hpp>
#include <ostream>
#include <type_traits>
#include <iostream>
template<int N>
struct TestStruct {
template<int E = N, std::enable_if_t<E == 1, int> = 0>
std::string to_string() const { return "to_string"; }
template<int E = N, std::enable_if_t<E == 2 || E == 3, int> = 0>
friend std::ostream& operator<<(std::ostream& os, const TestStruct&) { os << "operator<<"; return os; }
std::string ToString() const { return "ToString"; }
};
template<int N>
void test() {
sol::state s;
s.open_libraries(sol::lib::base);
auto meta = s.new_usertype<TestStruct<N>>("__TEST", sol::no_constructor);
if constexpr (N == 4) {
meta["__tostring"] = &TestStruct<N>::ToString;
}
if constexpr (N == 3) {
s["__TEST"] = nullptr;
}
s["TEST"] = TestStruct<N>{};
try {
std::cout << "\n\n\n";
auto res = s.script("print('TEST', TEST)print('__TEST', __TEST)");
if (!res.valid()) {
sol::error err = res;
std::cout << N << " " << err.what() << "\n";
}
else {
std::cout << N << " OK!\n";
}
}
catch (const sol::error& err) {
std::cout << N << " !Exception! " << err.what() << "\n";
}
}
int main() {
test<1>();
test<2>();
test<3>();
test<4>();
}
Ah, this looks like it might be calling to_string on the special table itself. Which is wrong.
I can see the problem at least in my head, now I gotta fix it..