Thread: Library for OOP and exception handling

  1. #1
    Registered User
    Join Date
    Dec 2019
    Posts
    2

    Library for OOP and exception handling

    Hello,

    Yesterday I've implemented a C library that offers support for classes with inheritance and polymorphism, as well as exception handling. Obviously, it's not recommended for new projects. If these features are needed for such a project, I would recommend sticking to a different language, such as C++, which offers explicit support for them. The target audience is developers stuck with an existing C code base that is too expensive to rewrite in a sane language but would prefer to be able to structure their C code in a manner that the language doesn't normally allow for.

    The library is standards-compliant so it should work with any hosted C99+ implementation. It is consistent with C11's threading model and I've written it in a way that it's easy to extend with pthread support, since many C99 programs might wish to use them. After I do that, I plan on releasing it on GitHub, under the LGPL license.

    Client code might look something like this (ignore the style, it's just compact for this particular paste):

    Code:
    #include <mcl/mcl.h>
    #include <stdarg.h>
    #include <stdio.h>
    
    void myclass1_ctor(void *const o, va_list args) { puts(__func__); }
    void myclass1_dtor(void *const o) { puts(__func__); }
    void myclass2_ctor(void *const o, va_list args) { puts(__func__); }
    void myclass2_dtor(void *const o) { puts(__func__); }
    void myclass3_ctor(void *const o, va_list args) { o->v = va_arg(args, int); puts(__func__); }
    void myclass3_dtor(void *const o) { puts(__func__); }
    
    struct myclass1 { class *desc; };
    struct myclass2 { class *desc; };
    struct myclass3 { class *desc; int v; };
    
    class myclass1_desc = { sizeof (struct myclass1), NULL, myclass1_ctor, myclass1_dtor },
          myclass2_desc = { sizeof (struct myclass2), &myclass1_desc, myclass2_ctor, myclass2_dtor },
          myclass3_desc = { sizeof (struct myclass3), &myclass2_desc, myclass3_ctor, myclass3_dtor };
    
    int main(void) {
        struct myclass1 *o1 = new(&myclass1_desc), *e1 = new(&myclass1_desc);
        struct myclass2 *o2 = new(&myclass2_desc), *e2 = new(&myclass2_desc);
        struct myclass3 *o3 = new(&myclass3_desc, 42), *e3 = new(&myclass3_desc, 0);
    
        try { throw(o2);
        } catch (e1) { puts("myclass1 handler; caught by superclass");
        } catch (e2) { puts("myclass2 handler; not caught");
        } catch (e3) { puts("myclass3 handler; not caught");
        } finally { puts("done"); }
    
        try {
            throw(o3);
        } catch (e3) {
            printf("%d\n", e3->v);
        } catchall {
            puts("generic handler");
            rethrow;
        }
    
        delete(o1); delete(e1);
        delete(o2); delete(e2);
        delete(o3); delete(e3);
    }
    Each class starts with a pointer to a descriptor for internal use. These descriptors specify things like the parent class, the constructor, the destructor, and the vtable associated with a particular class. Here, myclass3 is a subclass of myclass2, which is a subclass of myclass1. They all have constructors and destructors (although they don't need to) and none have any virtual functions.

    Unfortunately, there's no way to catch types so the appropriate exception handler is selected based on the type of the object passed to catch, which will then get the thrown value copied into it. The finally block (I've borrowed Java's keyword) is necessary for clean-up work, since C does not have RAII.

    Before I release it, got any suggestions for other features you might find useful and like to see? If they don't take too much time to implement, I might get around to them.

    Cheers,
    Bogdan
    Last edited by Love4Boobies; 12-19-2019 at 07:02 AM.

  2. #2
    Registered User
    Join Date
    Dec 2019
    Posts
    1
    Ah, the weekly "Ive implemented exceptions and classes in C!" thread.
    Spoiler alert: you haven't.
    Last edited by sweeney; 12-19-2019 at 07:25 AM.

  3. #3
    Registered User
    Join Date
    Dec 2019
    Posts
    2
    Hmm?

    Okay, I've published it... Here it is.

    EDIT: Funny that you've made an account just to embarrass yourself.

    By the way, since this came up elsewhere: those e's used for catching exception values do not need to be dynamically allocated. You can easily do something along the lines of:

    Code:
    struct myclass e = { &myclass_desc };
    
    try {
        // ...
    } catch (&e) {
        // ...
    }
    Last edited by Love4Boobies; 12-19-2019 at 08:37 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Exception errors OR exception handling :S
    By cruiser in forum C++ Programming
    Replies: 4
    Last Post: 09-02-2011, 05:30 AM
  2. Exception Handling
    By forumuser in forum C++ Programming
    Replies: 5
    Last Post: 09-18-2009, 03:17 AM
  3. signal handling and exception handling
    By lehe in forum C++ Programming
    Replies: 2
    Last Post: 06-15-2009, 10:01 PM
  4. ATL exception handling
    By rzcodeman in forum Windows Programming
    Replies: 1
    Last Post: 06-10-2004, 06:19 PM
  5. Exception handling
    By kuwait in forum C++ Programming
    Replies: 4
    Last Post: 12-11-2003, 06:20 AM

Tags for this Thread