Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A const C++ container can be modified in Lua (want it to be truly const) #1587

Open
totalgee opened this issue Mar 6, 2024 · 0 comments
Open

Comments

@totalgee
Copy link

totalgee commented Mar 6, 2024

I'd like to expose a const container (here it happens to be a std::vector) to Lua via Sol, so it can be iterated/accessed there but not modified. I thought that exposing a const ref to the thing (rather than a ref) would prevent modifications to it via Lua, but there is no error when I try to add elements in various ways; I actually manage to modify the "const" declared C++ vector!

Compiler: Visual Studio 2022, C++17 or C++20
OS: Windows 11 Pro

Here is an example that shows the problem, and what I'm trying to do. It's basically a slightly modified version of your example from the documentation, but where I tried to make the vector constant:

#include "sol/sol.hpp"

int main() {
    sol::state lua;
    lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::os, sol::lib::string);

    lua.script(R"lua(
function printContainer(x)
	print("\ncontainer has:")
	for k = 1, #x do
		v = tostring(x[k])
		print("\t", k, v)
	end
end
	)lua");

    sol::function printContainer = lua["printContainer"];

    // Expose a constant vector to Lua
    // (first tried exposing as a cref, and then I even tried setting the underlying variable as const!)
    auto const arr = std::vector<int>{ 2, 4, 6, 8, 10 };
    lua["arr"] = std::cref(arr);
    printContainer(lua["arr"]);
    std::cout << "Size of C++ arr: " << arr.size() << '\n';

    // Presumably we shouldn't be able to get a non-const reference to it...?
    std::vector<int>& reference_to_arr = lua["arr"];
    reference_to_arr.push_back(12);

    // See *6* elements printed out (but it's supposed to be const)
    printContainer(lua["arr"]);
    std::cout << "Size of C++ arr: " << arr.size() << '\n';

    // Modify it from Lua
    lua.script(R"(
arr:add(28)
	)");

    // See *7* elements printed out (again, it's intended to be const)
    printContainer(lua["arr"]);
    std::cout << "Size of C++ arr: " << arr.size() << '\n';

    return 0;
}

The program outputs:

container has:
                1       2
                2       4
                3       6
                4       8
                5       10
Size of C++ arr: 5

container has:
                1       2
                2       4
                3       6
                4       8
                5       10
                6       12
Size of C++ arr: 6

container has:
                1       2
                2       4
                3       6
                4       8
                5       10
                6       12
                7       28
Size of C++ arr: 7

Ideally, I'd like to have the exposing as const "just work", but I guess it may be necessary to create my own container type...? I would expect it to give an error if I try to modify it. Maybe something like what happens if I use a const variable in Lua and then try to change it:

local x <const> = 3
x = 7

Which produces:

[sol2] An error occurred and has been passed to an error handler: sol: syntax error: [string "..."]:3: attempt to assign to const variable 'x'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant