Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2000-11-20 11:15:59


On Mon, 20 Nov 2000 00:12:59 -0800
Karl Nelson <kenelson_at_[hidden]> wrote:

[snip]
> > Will return this error message with g++-2.95.2:
> >
> > callback1.cpp:22: instantiated from here
> > ../../boost/callback.hpp:236: `function_call_operator_signatures_are_not_comp
> > atible_with_callback' is not a member of type `boost::INVALID_CALLBACK_TARGET
> > <hello_world>'
>
> Better, though not quite
> 'no match for callback<void,int> = callback<void,int,int>'

Maybe in the next iteration :).
 
> > More metaprogramming could yield more accurate error messages, but VC++ has b
> > ecome the limiting factor.
>
> VC++ is always a limiting factor. I had to jump through a hell
> of a lot of huddles to get my code to work there and some of the
> template formulations still cause random errors. I hope that
> someday everyone here comes to realize how worthless that
> sorry excuse for a compiler is and boycots it.

This sentiment was expressed and discussed a few months ago (when it was noted that VC++ 7.0 would be no better), but the overriding concern seemed to be that several Boosters have to use VC++ at work, and Boost would be of less value to them if they can't use it at work. In any case - if I can get good error messages out of a real compiler, I'll happily #ifdef out those portions for VC++.

> Speaking of lame compilers, not all compilers have void returns.
> For those without it like VC++ you can use the int return trait trick.
> However, on others like SGI compiler this may fail. For SGI you would
> need to specialize callback<void,...> and all the implementations
> using partial specialization.

IMHO, using partial specialization is the better choice in any case. I worry about the portability of the int casting trick.

> (This is one of the things the really confused people in SigC, there
> are multiple formulations there to cover the bad case compilers. It
> makes for reams of code which just gets skipped on most compilers.)

After uploading the newest version of the callback library yesterday I was lamenting the ugliness of the resulting code. As careful as I was, the VC++ hacks have produced almost illegible source from reasonably simple code.

>
> So lets look at another minor issue. That is the virtuals tables.
> I benchmarked your callbacks against SigC 1.1 slots for binary size.
> I implemented 21 functors like this
>
> struct func_float_int_int
> {
> float operator()(int a, int b) { return float(a*b); }
> };
>
> for combinations of float, int, and double. In then made one
> callback for each functor, set it and called it. The
> resulting binary was 430k debug and 30K striped. Most of the space was
> nothing but almost wothless typeinfo functions.
>
> 00000094 W boost::detail::functor_callback<func_int_int_int, int, int, int, boost::detail::Unused> type_info function
>
> SigC 1.1 formulation on similar test was 90k debug and 17.4k striped.
> (done with static linking though much of is sharable in a library)
> This difference came because SigC didn't use the virtual table to launch the
> callback but instead a function pointer. However, I don't believe
> a similar technique is possible in your code.

I think this is an unfortunate cost of generality, and I don't see how we can safely call operator() in an arbitrary functor without type_info. Perhaps there is still sufficient magical energy in (type)casting to make this work portably.

> This raise the problem I expressed before, that if you use a large
> number of functor types it can eat a lot in binary size. It doesn't
> look to extreme for your library, but you should test with
> reasonable numbers of callbacks and functors to see how much it scales.
> I only optomized SigC because gtk-- used several hundred which
> would have added 2M to the library binary size in typeinfo and
> similar stuff.
>
> Hope it helps.

It does.

        Doug Gregor


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk