Search code examples
ccompiler-constructioninterpretervm-implementation

Is there some way to use pointers inside C switch statements?


Usually in a dynamically typed programming language, the object struct has a tag field used to identify the object type. For example:

struct myObject {
    int tag;
    ...
}

So it is easy to perform different actions using a switch statement based on the tag field. For example:

switch (obj->tag) {
    case OBJ_INTEGER: ...
    case OBJ_STRING: ...
    case OBJ_FUNC:...
}

In my case instead of the int tag field I used a void *isa pointer that points to the class that represents that object. Everything worked fine expect that instead of using an elegant switch statement I am forced to use a series of if/else statements. For example:

if (obj->isa == class_integer) {
    ...
} else if (obj->isa == class_string) {
    ...
} else if (obj->isa == class_func) {
    ...
}

I know that I can't use pointers inside a C switch statements but I wondering if I can use some clever trick in order to speedup the series of if statements.


Solution

  • The beauty of having isa pointer in the first place is an ability to dispense with switch statements completely.

    Consider a switch:

    switch (obj->tag) {
        case OBJ_INTEGER: do_something_int(obj); break;
        case OBJ_STRING: do_something_str(obj); break;
        case OBJ_FUNC: do_something_func(obj); break;
    }
    

    Let's say that isa pointer points to some struct which you own - say, struct dyn_type. Add a function pointer to your struct, like this:

    typedef void (*ProcessPtr)(dyn_obj * obj);
    
    struct dyn_type {
        ... // fields of your current struct
        ProcessPtr process;
    };
    

    Set process field to do_something_int for OBJ_INTEGER, do_something_str for OBJ_STRING, etc. Now you can replace switch with

    ((struct dyn_type*)obj->isa)->process(obj)