Boost logo

Boost :

Subject: Re: [boost] [function] new implementation
From: Hartmut Kaiser (hartmut.kaiser_at_[hidden])
Date: 2010-10-30 13:26:34


> <...those that followed the latest function related discussions can skip
> the first paragraph...>
>
> For about a year and half now (or even more but that's about how long I've
> been involved in the matter) there have been repeated
> discussions/requests/complaints about various aspects of Boost.Function.
> Most of those fall into one or more of these categories:
> - overall code speed overhead
> - overall code bloat overhead
> - lack of configurability
> - dependencies on RTTI and exception handling with the most frequently
> brought up specific issue being the various implications (in all of the
> above mentioned areas) of the hardcoded throw-on-empty behaviour...
>
> Unfortunately Boost.Function code remained virtually unchanged (except for
> the added RTTI emulation for platforms w/o RTTI support) with all of the
> issues still remaining...
>
> The new implementation proposal @:
> https://svn.boost.org/svn/boost/sandbox/function/boost/function
> http://www.boostpro.com/vault/index.php?&direction=0&order=&directory=Func
> tion
> Objects
> solves or at least provides drastic improvements for all of the mentioned
> issues.

That looks promising. Therefore, I tried to replace boost::function with
your new implementation. Everything compiled fine but things got ugly when I
was running my applications. I was seeing unexpected exceptions from
apparently empty function object instances. I little investigation brought
up the following. The code failing is roughly this:

#include <boost/function.hpp>

struct A
{
  A (boost::function<void()> f = boost::function<void()>())
    : func(f)
  {}

  void call()
  {
      if (func) // returns wrong result
          func();
  }

  boost::function<void()> func;
};

int main()
{
    A a;
    a.call();
    return 0;
}

where 'if (func)' returns true even if func has been initialized from the
default (and empty) default argument.

Apparently, the code above works just fine as long as everything is compiled
into a single executable, but it starts failing if A::call() is implemented
in a separate shared library (this problem is probably limited to Windows
platforms as well, as there each module gets its own instances of static
data members).

So, the culprit is this static data member (function_base.hpp, line 1016):

    static vtable const stored_vtable;

which is not unique anymore in applications consisting out of several
(shared) modules/dlls. The consequence is that function_base::empty()
returns wrong results for function objects created in one module, but
checked inside another one.

Regards Hartmut
---------------
http://boost-spirit.com


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