简体   繁体   中英

C: Pointers to any type?

I hear that C isn't so type-safe and I think that I could use that as an advantage for my current project.

I'm designing an interpreter with the goal for the VM to be extremely fast, much faster than Ruby and Python, for example.

Now I know that premature optimization "is the root of all evil" but this is rather a conceptual problem.

  • I have to use some sort of struct to represent all values in my language (from number over string to list and map)

Would the following be possible?

struct Value {
 ValueType type;
 void* value;
}
  • I would store the actual values elsewhere, eg: a separate array for strings and integers, value* would then point to some member in this table.

  • I would always know the type of the value via the type variable, so there wouldn't be any problems with type errors.

Now:

Is this even possible in terms of syntax and typing?

Yes, you can use a void* to point to anything, and then cast it to the proper type when needed (that's how malloc and such can work).

void* is basically "pointer to an arbitrary block of memory".

If you know the range of types you want to support, this could easily be done with a union to avoid casts all over the place:

struct Value
{
    ValueType type;
    union
    {
        int*        iptr;
        char*       sptr;
        float*      fptr;
        struct map* mptr;

        /* ... */

        void* vptr; /* catch all, extensions */

    } ptrs;
};

Sure it is. You will only need a big switch on type to distinguish the type of a particular value. The best type to use for your field type will probably be an enum with a constant for each of the types of your language, like so:

typedef enum type {
    Integer,
    String,
    /* and so on... */
} ValueType;

Also remember you have to cast the void* pointer to a particular type before using it.

There are varying degrees of type safety, but since C is a strongly typed language, it's actually on the safer end of the spectrum. That won't stop you from doing what you propose. The example you give is syntactically valid, and could be used to implement the system you describe. Keep in mind, though, that if you go ahead and try to reinvent the wheel by creating your own VM, you're very unlikely to beat the performance of existing languages like Ruby and Java.

The good news: someone else thought of that. See Variant. (for example http://en.wikipedia.org/wiki/Variant_type and http://msdn.microsoft.com/en-us/library/x295h94e(VS.80).aspx .) The bad news: those of us who worked with them generally came to hate them.

It's okay to write that code, but maybe you've to design your "language" (ok, interpreter :) ) before other things.

Btw, I suggest you to read the object oriented programming in c book . When you've understood the main concepts, you can look at the implementation of Python Objects , so that you can think about how methods interact with objects and how they are stored, and so on.

Bye bye!

Check out CCAN's type safe callbacks for macros that help you avoid bad casts. I know you aren't writing a callback, but lots of callbacks look like this:

void my_callback(void *context)

And several types may be cast to (void *) and passed to context . Casting within that function gets tricky, especially if the callback launches a thread that takes a single (void *) argument.

Anyway, you might find some useful bits if you follow the link.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM