Objects without classes - data model in 'clean C'

c, c++, c++11, procedural-programming

Solution

But it's surprisingly hard to find any resources on how to take the best of both worlds.

Because there isn't one. The only reason to do such a thing is because you're desperate for compatibility- for example, Lua is written in "clean C". There's nothing "best" about it at all.

It's just C code pretending to be terrible C++ code. It's not C++ code but compatible. There's nothing better about "clean C" than regular C.

Edit: You, sir questioner, appear to have no idea WTF "clean C" even is. It's making your source code, even the implementations, C code that compiles as C++. No namespaces, no types, no constants, no nothing. C++-with-a-C-interface is a wholly different thing and totally unrelated to clean C. And in that case, there is no reason to limit which C++ features you use in the implementation.

Problem

I've worked with C++ on some medium-sized project, but I have never did any serious programming in C. Having read this article I've started wondering how I could use C++11 without classes and exceptions. I once heard the term clean C. Clean C supposed to be a C++ code which doesn't use C++ features that ANSI C doesn't have, like classes or metaprogramming. There's plenty resources how to do things in C effectively and how to do them in C++. But it's surprisingly hard to find any resources on how to take the best of both worlds. My question is two-part: - Are there any good resources on using the C++ without namespaces, exceptions and metaprogramming? Books, open source projects? - Please review this simple piece of code, which is my first attempt on handling data structures and char strings in mentioned subset of C++11. First thing comes to my mind is code redundancy. What woud you do differently and why? ``` #include <cstring> namespace addressbook { namespace contact { struct contact { char* name; char* email; }; void initialize(addressbook::contact::contact* contact) { contact->name = nullptr; contact->email = nullptr; } void deinitialize(addressbook::contact::contact* contact) { delete[] contact->name; delete[] contact->email; } void set_name(addressbook::contact::contact* contact, char* name) { delete[] contact->name; contact->name = new char [strlen(name) + 1]; std::strcpy(contact->name, name); } void set_email(addressbook::contact::contact* contact, char* email) { delete[] contact->email; contact->email = new char [strlen(email) + 1]; std::strcpy(contact->email, email); } } // namespace contact } // namespace addressbook int main() { namespace c = addressbook::contact; c::contact jimmy; c::initialize(&jimmy); c::set_name(&jimmy, const_cast<char*>("Jimmy Page")); c::set_email(&jimmy, const_cast<char*>("jp@example.com")); c::deinitialize(&jimmy); return 0; } ``` Please have mercy upon me - I'm a structural programming newbie. Why not just C then? Namespaces, new/delete, standard library algorithms, boost libraries, C++11 cool features - to name a few. Why new/delete when you don't have constructors/destructors? Because of type safety. `malloc` returns `*void` But standard library throws exceptions! And boost does too! The fact that I'm not using exceptions doesn't mean I can't handle exceptions coming from external libraries. It just means I want to manage problems differently in my part of the system.

Original source