"C with classes" revisited

Ever wondered why these Cold War era C/C++ stacks are so messy? They consist of trivial preprocessing, unstable linking, perverse templates, non-determined-exactly-size-but-less-than-you-need integers and more. When writing https://git.sr.ht/~anek/werewolf (the Boost.Beast/Lua bridge), I've unavoidingly stumbled at every embedded C++ coder' issue: writing C++ wrappers of C libraries. Let's look at my code: void lua_vm::getglobal(const std::string &key) { lua_getglobal(state(), key.c_str()); } void lua_vm::push_string(const std::string &str) { lua_pushlstring(state(), str.data(), str.size()); } void lua_vm::push_number(size_t num) { lua_pushnumber(state(), num); } Looks familiar? Hell yeah. What if we revisit C++ namespaces/classes/structs/preprocessing? namespace context { struct context *create(); void delete(struct context *); int method1(struct context *ctx, int arg1); int method2(struct context *ctx, int arg2); } struct context { int field1; int field2; }; class context { using namespace context; using struct context; }; Working name for this spontaneous attempt (I'm late at night, you know) is Holy C++.

Feb 12, 2025 - 22:43
 0
"C with classes" revisited

Ever wondered why these Cold War era C/C++ stacks are so messy? They consist of trivial preprocessing, unstable linking, perverse templates, non-determined-exactly-size-but-less-than-you-need integers and more.
When writing https://git.sr.ht/~anek/werewolf (the Boost.Beast/Lua bridge), I've unavoidingly stumbled at every embedded C++ coder' issue: writing C++ wrappers of C libraries. Let's look at my code:

void lua_vm::getglobal(const std::string &key)
{
    lua_getglobal(state(), key.c_str());
}

void lua_vm::push_string(const std::string &str) {
    lua_pushlstring(state(), str.data(), str.size());
}

void lua_vm::push_number(size_t num) {
    lua_pushnumber(state(), num);
}

Looks familiar? Hell yeah.

What if we revisit C++ namespaces/classes/structs/preprocessing?

namespace context {
        struct context *create();
        void delete(struct context *);
        int method1(struct context *ctx, int arg1);
        int method2(struct context *ctx, int arg2);
}
struct context {
        int field1;
        int field2;
};
class context {
        using namespace context;
        using struct context;
};

Working name for this spontaneous attempt (I'm late at night, you know) is Holy C++.