[20051221]
|
Tripping over not-so-standard standard types
Well, or maybe just non-standard use of them. Trying to build
qemu 0.8 today (with SMP for i386 and sparc!), I tripped over
some evil code that builds symbols from types using some
extended cpp(1) magic:
#define IN_T int8_t
...
#define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
...
static void glue (glue (conv_, ET), _to_mono)
(st_sample_t *dst, const void *src, int samples, volume_t *vol)
{ ... }
t_sample *mixeng_conv[2][2][2][2] = {
{
{
{
conv_natural_uint8_t_to_mono,
conv_natural_uint16_t_to_mono
}
...
(Some data ommitted, see audio/mixeng.c and audio/mixeng_template.h).
This led to fireworks, as conv_natural___uint8_t_to_mono
was not defined - note the two extra underscores!
As it turns out, the NetBSD 2.x system I did this on actually has uint8_t
(and others) as a #define to the corresponding types with __, which
then leads to the above effect. Of course the right way is not to
use #define but typedef here, but upgrading to NetBSD 3.0 (which does
the right thing) is not an option right now).
So I tried to come up with some equally evil cpp(1) magic to expand
the symbol in the second place, replacing:
conv_natural_uint8_t_to_mono,
conv_natural_uint16_t_to_mono
with
NBglue(conv_natural_, uint8_t, _to_mono),
NBglue(conv_natural_, uint16_t, _to_mono)
the idea here was to add a
#define NBglue(x,y,z) x ## y ## z
that does the right thing, but it didn't - the "y" symbol
was not expanded by cpp(1)! I tried a second version:
#define NBexpand(x) x
#define NBglue(x,y,z) x ## NBexpand(y) ## z
but here again the symbol was not expanded but used literally,
and I got complaints that "conv_natural_NBexpand(uint16_t)_to_mono"
was not a valid symbol - surprise. So the final answer was -- thanks
to Christos at this point! -- this one:
#define _NBglue(x,y,z) x ## y ## z
#define NBglue(x,y,z) _NBglue(x,y,z)
This expands the types properly.
What lesson can be learned from this? 1) don't use #define where typedef
is the right thing 2) don't blindly assume someone followed rule 1).
Oh, and someone please feel free to go back and clean up this whole code,
apparently it was de-C++-ified at some time, according to some comment... :)
And finally, if someone's got some success with the kqemu or that
other kernel-module whose name I forgot, please let me know! :)
[Tags: hubertf, qemu]
|