> In this case I’m in control of both C and Lua code, so I am happy to assert that will never happen.
Sure, but you still have a dependency on undocumented implementation details.
> I load the configuration as a Lua file into the state and pcall() it, then the C code retrieves the values it needs from the Lua state. The configuration might have hundreds of string values and it would be a shame if I had to resort to strdup(lua_tostring()), duplicating and handling my own memory for such a trivial task. Leaving the strings on the stack would easily fill the stack, and I’d need more boiler plate to check that I hadn’t already left that particular string on the stack.
lua_checkstack: "typically at least several thousand elements"
I think you can just leave all those values on the API stack. That will work as long as you never have to reload your config. If you do, you will have to consider all the previously obtained string pointers invalid, nuke and reload the Lua state, and refetch the config strings. Note that keeping those string values referenced in the registry vs keeping those values on the API stack is probably going to need comparable amounts of memory. You can save on memory only if you avoid both the registry and the stack, which again would mean relying solely on implementation details. The question is, how much that would really save in the grand scheme of things, given that you are talking about hundreds of strings.