Mailing List Archive

C method-invocation API improvement
Greets,

Today, I believe I solved a problem with the C-space OO implementation
in KS. Method calls have been implemented as "unsafe macros", so
called because they evaluate an argument twice. Here's an example
from the current dev release, 0.20_051:

#define Kino_SegPList_Next(self) \
(self)->_->next((kino_PostingList*)self)

The problem with such macros is that they can cause problems if the
multi-evaluated argument has side effects. For example, invoking this
method once causes i to be incremented twice...

SegPList_Next(seg_posting_lists[i++]);

... as the macro expands out to this:

(seg_posting_lists[i++])->_-
>next((kino_PostingList*)seg_posting_lists[i++]);

The solution is to use static inline functions instead of macros:

extern size_t Kino_SegPList_Next_OFFSET;
static CHY_INLINE chy_u32_t
Kino_SegPList_Next(const void *vself)
{
kino_PostingList *const self = (kino_PostingList *)vself;
char *const method_address = (char*)self->_ +
Kino_SegPList_Next_OFFSET;
const kino_PList_next_t method =
*((kino_PList_next_t*)method_address);
return method(self);
}

Any optimizing compiler ought to have no trouble reducing that to
extremely efficient machine code. I did a little experiment today and
GCC gave me *exactly* the assembler I wanted. Furthermore, the
compiled size of the shared library was the same before and after the
change.

Now, when we publish a C API for KinoSearch, there should be no need
for caveats or caution regarding method invocation syntax.

Marvin Humphrey
Rectangular Research
http://www.rectangular.com/


_______________________________________________
KinoSearch mailing list
KinoSearch@rectangular.com
http://www.rectangular.com/mailman/listinfo/kinosearch