Improving efficiency of a bytecode interpreter

B

Bill Cunningham

C is chosen as it is an efficient "bare metal" language in most
cases. Naive design listening to his "never optimise too early" nonsense
can often counter that.

On C. .5/10
 
M

Mark R. Bannister

Then use (a) and live with all the casts.  I don't see another way to
avoid the problem.

Can you give me an example of what you mean by (a)? I don't mean to
be thick, maybe I'm missing something, but I don't see how that would
work.

Thanks,
Mark.
 
B

Ben Bacarisse

Mark R. Bannister said:
Can you give me an example of what you mean by (a)? I don't mean to
be thick, maybe I'm missing something, but I don't see how that would
work.

Lets start by naming two function types to simplify the examples:

typedef int cmp_voidp(const void *, const void *);
typedef int cmp_stringp(const struct String *, const struct String *);

You have a function that takes one or more parameters with a type of
"pointer to cmp_voidp":

int example(cmp_voidp *f)
{
/* ... */
}

The call

exmaple(STRcmp);

gives you a warning, because STRcmp is of type cmp_stringp and
evaluates to a pointer of type cmp_stringp * rather than cmp_voidp *.
To avoid the warning you must first cast the call:

example((cmp_voidp *)STRcmp)

You might be tempted to stop here since the warnings have gone away,
but that is the danger of casts. Inside example, you must cast the
pointer back to the type of the function actually being called. Since
the whole point of this is that 'example' gets passed lots of
different function types you will have lots of different casts decided
when you know what type of function you are calling:

int example(cmp_voidp *f)
{
/* ... */
switch (data->type) {
case TYPE_VOIDP:
return f(p1, p2); /* correct type already */
case TYPE_STRINGP:
return ((cmp_stringp *)f)(p1, p2);
/* ... */
}
}

In the second case, p1 and p2 are converted to pointers of the right
type because the function pointer has been cast. Without the cast, a
call like

example((cmp_voidp *)STRcmp)

causes STRcmp to be called with void * parameters silently interpreted
as struct pointers. This works on most machines you will find but is
technically wrong and does break on some odd hardware.
 
M

Mark R. Bannister

Lets start by naming two function types to simplify the examples:

  typedef int cmp_voidp(const void *, const void *);
  typedef int cmp_stringp(const struct String *, const struct String *);
<snip>

Thanks Ben, this is all new to me. Despite programming C for almost
15 years and having some very good C reference books, I'm embarrassed
to say in all that time I never knew that you could cast function
types or even typedef functions. Well, I'm always open to learning
and trying new things, so here we go ..... !
 
B

Ben Bacarisse

Mark R. Bannister said:
<snip>

Thanks Ben, this is all new to me. Despite programming C for almost
15 years and having some very good C reference books, I'm embarrassed
to say in all that time I never knew that you could cast function
types or even typedef functions. Well, I'm always open to learning
and trying new things, so here we go ..... !

It is much more common to typedef function pointer types rather than
the function types themselves, but there are some advantages to the
latter. For example, it lets you declare a bunch of similar functions
very compactly:

typedef void binary_op(struct state *, struct value, struct value);

extern binary_op op_add, op_sub, op_mul, op_div /*...*/;

static binary_op *op_table[] = {
op_add, op_sub, op_mul, op_div /*...*/
};

The translation unit that defines the op_xxx functions needs to have
the parameters written out in full every time (with names this time)
but there is no need to do that just to declare them all.
 
K

Keith Thompson

Mark R. Bannister said:
<snip>

Thanks Ben, this is all new to me. Despite programming C for almost
15 years and having some very good C reference books, I'm embarrassed
to say in all that time I never knew that you could cast function
types or even typedef functions. Well, I'm always open to learning
and trying new things, so here we go ..... !

But you can't cast (or otherwise convert) function types. You can
cast pointer-to-function types.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top