
Hi, <...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=Function Objects solves or at least provides drastic improvements for all of the mentioned issues. It is intended as a drop in replacement for the current implementation and as such I have so far tested it in the following ways: - compiling some real world code: VC10, GCC 4.2.1, LLVM-GCC 4.2.1, GCC 4.5.1, GCC 4.6, Clang 2.0, Clang 2.8 - compiling and running a real world project: VC10, Clang 2.8 - building Boost trunk: VC10, GCC 4.2.1, GCC 4.5.1, Clang 2.0 - running Boost regression tests for Function, Signals, Signals2, Thread, Program Options and Graph libraries: VC10, GCC 4.2.1, Clang 2.0. (All of the tests passed except for two bogus assertion failure boxes that pop up with VC10 and the Program Options tests during the automated regression test procedure that OTOH do not popup when I run the same tests manually through the VC10 IDE, i.e. the tests finish successfully...I tried to make sure all the relevant compiler switches were the same in both cases so I am out of ideas what else can make the difference.....) Next, let me give you a comparison of for-size-optimized code generated by VC10 with both the current and the proposed implementation for a short code snippet demonstrating invocation, construction and assignment: struct X { int foo( int const x ) const { return x + y; }; int y; }; int main( int /*argc*/, char * * /*argv*/ ) { using namespace boost; X x; function<int(int)> foof( boost::bind( &X::foo, &x, _1 ) ); foof( 0 ); function<int(int)> barf; barf = foof; barf( 1 ); return 0; } Notice in new_function_code_listing.txt how all of the wrapper code in the new Function was completely transparent to the compiler and was completely inlined to relatively simple machine code with direct calls to/through the vtable pointers...while OTOH in current_function_code_listing.txt the code generated for the "barf = foof;" assignement alone is several times larger than the entire code generated for the new Function implementation. The small asm snippet of the generated invoker/'thunk'/'trampoline' code also demonstrates the effects of various tweaks done to minimize or all together remove the need for any stack adjustment on the invoker side... The new implementation of course has the same semantics and exception safety guarantee levels as the original/current one. Listing all of the improvements and detailed implementation changes here in the first post would be quite cluttering as they are quite numerous. Those that desire more tests and details right now, can follow this trail: http://lists.boost.org/Archives/boost/2010/01/160908.php As for the dependencies issue this is solved in several ways: - use of exception handling: new code uses guard objects instead of explicit exception handling and provides a way to change on-empty-behaviour so that the EH code/dependency can easily be removed/disabled - use of RTTI (for getting the type of the stored function object): this can be globally disabled with the BOOST_FUNCTION_NO_RTTI macro. BOOST_NO_RTTI is not used for this purpose for backward compatibility reasons: in the current implementation it actually turns on RTTI emulation...The idea is to also add per instantiation RTTI on-off configurability... 'Configurability' will probably be the most controversial issue/change because it required the addition of an extra template parameter through which an MPL list of policies can be specified at compile-time. This parameter is properly defaulted to allow existing code to compile without changes while providing current Boost.Function behaviour (e.g. on-empty- behaviour). As all the performed tests showed this to also be true in practice the proposed code should IMO go in as a straight drop-in replacement but, of course, I might have missed some important higher level detail/concern so this is open to discussion... Currently two policies are supported: - on throw behaviour (with throw-on-empty, nop-on-empty and assert-on-empty handlers provided) - whether the function instantiation should mark itself (i.e. its operator()) as nothrow. Additional policies my be added later, for example: - sizeof and/or alignment of the SBO buffer - default allocator - per instantiation RTTI on/off ... Finally, there is one more addition, somewhat 'unholy' as it brings in the concept of binding into Boost.Function but considering its efficiency and/or verbosity benefits (and the fact that the first issue can be 'explained away' by saying that this is not actually 'binding' but a workaround for the lack-of-delegates-support C++ language deficiency). The addition is in the form of two more assign() member function overloads (one for a free function that has the exact signature as the Boost.Function instantiation, and one for a member function that has a matching signature with the addition of a this pointer) that allow assignment of (suitably typed) plain (free or member) functions specified as non-type-template parameters. This allows for the removal of the extra indirect-call-through-function-pointer otherwise incurred by traditional assignment of function pointers (not functors), which is actually a rather common use case. For example, in the above example given, one can now write: foof.assign<X, &X::foo>( x ); and get a trivial invoker with the X::foo() target function inlined straight in... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

My apologies for resending, Windows Live Mail managed to crash when I pressed the 'Send' button and at the same time mangle the attached .txt files (line truncations)...so I'm resending those as .asm hoping the same thing will not happen again... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

On Sat, Oct 30, 2010 at 02:53:42PM +0200, Domagoj Saric wrote:
It is intended as a drop in replacement for the current implementation and as such I have so far tested it in the following ways: - compiling some real world code: VC10, GCC 4.2.1, LLVM-GCC 4.2.1, GCC 4.5.1, GCC 4.6, Clang 2.0, Clang 2.8 - compiling and running a real world project: VC10, Clang 2.8 - building Boost trunk: VC10, GCC 4.2.1, GCC 4.5.1, Clang 2.0
Quick tests show that (assuming I have grafted it into my 1.44 tree properly), this "drop-in" replacement does not work on neither VisualAge C/C++ 11.1 and SunStudio 12 (Sun C++ 5.9). I might add that the existing implementation of Boost.Function does work on those compilers. -- Lars Viklund | zao@acc.umu.se

"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101030132800.GJ22859@hatchepsut.acc.umu.se...
Quick tests show that (assuming I have grafted it into my 1.44 tree properly), this "drop-in" replacement does not work on neither VisualAge C/C++ 11.1 and SunStudio 12 (Sun C++ 5.9).
I would expect that the proposed code does not yet compile on the more defficient compilers as I first focused on getting a version working on more recent/more compliant compilers. As such there are certainly still places in code that rely on/use things like SFINAE and 'too-optimistic' use of integral constant compile time logic that is known to choke weaker compilers. When I get the time I will do some cleaning things up in this regard, however I unfortunately do not have access to the platforms you mentioned...but if you are interested and are willing to help maybe we can solve the issues you face ;) -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

"Domagoj Saric" <dsaritz@gmail.com> wrote in message news:iaieos$grm$1@dough.gmane.org...
"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101030132800.GJ22859@hatchepsut.acc.umu.se...
Quick tests show that (assuming I have grafted it into my 1.44 tree properly), this "drop-in" replacement does not work on neither VisualAge C/C++ 11.1 and SunStudio 12 (Sun C++ 5.9).
I would expect that the proposed code does not yet compile on the more defficient compilers as I first focused on getting a version working on more recent/more compliant compilers. As such there are certainly still places in code that rely on/use things like SFINAE and 'too-optimistic' use of integral constant compile time logic that is known to choke weaker compilers. When I get the time I will do some cleaning things up in this regard, however I unfortunately do not have access to the platforms you mentioned...but if you are interested and are willing to help maybe we can solve the issues you face ;)
SFINAE leftovers are removed and MSVC++ 8.0 and GCC 4.0.1 are added to the list of tested/working compilers... If you find the time/will to try again with VisualAge and SunStudio please send me the full compiler output if it still does not work...maybe I can fix it solely from that... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

On Wed, Nov 03, 2010 at 03:30:37PM +0100, Domagoj Saric wrote:
If you find the time/will to try again with VisualAge and SunStudio please send me the full compiler output if it still does not work...maybe I can fix it solely from that...
Grafting your function from sandbox r66384 into boost trunk r66339, I get the attached compiler outputs for the attached program. -- Lars Viklund | zao@acc.umu.se

"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101103190727.GL22859@hatchepsut.acc.umu.se...
On Wed, Nov 03, 2010 at 03:30:37PM +0100, Domagoj Saric wrote:
If you find the time/will to try again with VisualAge and SunStudio please send me the full compiler output if it still does not work...maybe I can fix it solely from that...
Grafting your function from sandbox r66384 into boost trunk r66339, I get the attached compiler outputs for the attached program.
Thanks a lot for the feedback... Try the new version... ;) -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

On Wed, Nov 03, 2010 at 09:37:24PM +0100, Domagoj Saric wrote:
Thanks a lot for the feedback... Try the new version... ;)
This compiles with SunStudio versions: * CC: Sun C++ 5.9 SunOS_sparc 2007/05/03 * CC: Sun C++ 5.10 SunOS_sparc 2009/06/03 xlC however, does not fare that well, logs attached. -- Lars Viklund | zao@acc.umu.se

"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101103213628.GM22859@hatchepsut.acc.umu.se...
This compiles with SunStudio versions: * CC: Sun C++ 5.9 SunOS_sparc 2007/05/03 * CC: Sun C++ 5.10 SunOS_sparc 2009/06/03
xlC however, does not fare that well, logs attached.
Nice, we're getting somewhere :) Try the new version ;) If this basic test now compiles, would you perhaps be willing to run some regression tests? ps. a side note, as a purely uneducated guess I would have thought that the IBM compiler is better than the Sun one, however, for the Sun compiler I only had to correct my own error while VisualAge seems to have problems with - out-of-parent-(non-template)-class definitions of member class templates - integral constant expressions in static asserts (but so does Clang and older GCCs) - RVO with classes that derive from boost::noncopyable (but so does Clang and all GCCs)... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

On 04.11.2010 11:07, Domagoj Saric wrote:
- integral constant expressions in static asserts (but so does Clang and older GCCs) - RVO with classes that derive from boost::noncopyable (but so does Clang and all GCCs)...
Have you filed bugs? RVO in Clang is not very advanced yet, but the ICE thing with static_asserts would be something we want to fix. Sebastian

"Sebastian Redl" <sebastian.redl@getdesigned.at> wrote in message news:4CD287ED.70301@getdesigned.at...
On 04.11.2010 11:07, Domagoj Saric wrote:
- integral constant expressions in static asserts (but so does Clang and older GCCs) - RVO with classes that derive from boost::noncopyable (but so does Clang and all GCCs)...
Have you filed bugs?
No, don't have time currently...waiting for the whole thing to stabilize...
RVO in Clang is not very advanced yet, but the ICE thing with static_asserts would be something we want to fix.
It's not an ICE but a compilation failure...as if the expression resolves to false...which OTOH resolves to true when checked at runtime with a BOOST_ASSERT... I was quite surprised to see that even the latest GCCs still have problems with integral constant expressions (even when I use the constexpr syntax)... ps. as a 'slight' off topic, since you seem to be involved in Clang development, you might want to make Clang a lot less eager to examine template code before it is instantiated (or add an option to that effect)...this sometimes acts as 'spiralling compile time killer' because it, for example, forces me to include headers that MSVC does not (or simply fails to compile 3rd party libraries like RapidXML)... The 'lazyness' of MSVC++ in template instantiation is probably one of the reasons why even Clang does not come near to it when it comes to compilation speed... Also the claim that Clang uses less RAM than GCC is not (always) true...with heavy template code (very convoluted mixtures of MPL and Fusion with typelist lengths up to 60) I've seen it eat 20-30% more than GCC 4.6 (but it still does compile faster, if you have enough RAM)... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

On 04.11.2010 11:30, Domagoj Saric wrote:
"Sebastian Redl" <sebastian.redl@getdesigned.at> wrote in message news:4CD287ED.70301@getdesigned.at...
RVO in Clang is not very advanced yet, but the ICE thing with static_asserts would be something we want to fix.
It's not an ICE but a compilation failure...
Sorry, I meant ICE as in "integral constant expression", not "internal compiler error". Those, we simply call crashes. ;-)
ps. as a 'slight' off topic, since you seem to be involved in Clang development, you might want to make Clang a lot less eager to examine template code before it is instantiated (or add an option to that effect)...this sometimes acts as 'spiralling compile time killer' because it, for example, forces me to include headers that MSVC does not (or simply fails to compile 3rd party libraries like RapidXML)... We can't, really. Clang is built from the ground-up to be eager in checking template code. It's pretty much part of the design.
The 'lazyness' of MSVC++ in template instantiation is probably one of the reasons why even Clang does not come near to it when it comes to compilation speed... Also the claim that Clang uses less RAM than GCC is not (always) true...with heavy template code (very convoluted mixtures of MPL and Fusion with typelist lengths up to 60) I've seen it eat 20-30% more than GCC 4.6 (but it still does compile faster, if you have enough RAM)... Yes, we know that C++ compilation uses a lot of memory. We have ideas to reduce it, but they're still not the top priority.
Sebastian

On Thu, Nov 04, 2010 at 11:07:53AM +0100, Domagoj Saric wrote:
"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101103213628.GM22859@hatchepsut.acc.umu.se...
This compiles with SunStudio versions: * CC: Sun C++ 5.9 SunOS_sparc 2007/05/03 * CC: Sun C++ 5.10 SunOS_sparc 2009/06/03
Nice, we're getting somewhere :) Try the new version ;)
If this basic test now compiles, would you perhaps be willing to run some regression tests?
All tests that shall pass pass, and the two that shall fail fail on 5.9 and 5.10 with r66387 and r66395. vacpp results are surprisingly good on r66395, log attached. It fails just two tests unexpectedly, lib_function_test and function_n_test. -- Lars Viklund | zao@acc.umu.se

"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101104112534.GN22859@hatchepsut.acc.umu.se...
All tests that shall pass pass, and the two that shall fail fail on 5.9 and 5.10 with r66387 and r66395.
vacpp results are surprisingly good on r66395, log attached. It fails just two tests unexpectedly, lib_function_test and function_n_test.
Ah, the dreaded 'ampersandless' plain function pointer assignment...this wrecks havoc on most compilers (including latest MSVC and Clang)... ...I've pretty much refactored the relevant code...try the new version and let me know if it helped... ps. if you can, please also run tests for signals, signals2 and program_options (these sometimes caught what the dedicated ones did not)... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

On Fri, Nov 05, 2010 at 10:54:17PM +0100, Domagoj Saric wrote:
"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101104112534.GN22859@hatchepsut.acc.umu.se...
All tests that shall pass pass, and the two that shall fail fail on 5.9 and 5.10 with r66387 and r66395.
vacpp results are surprisingly good on r66395, log attached. It fails just two tests unexpectedly, lib_function_test and function_n_test.
Ah, the dreaded 'ampersandless' plain function pointer assignment...this wrecks havoc on most compilers (including latest MSVC and Clang)... ...I've pretty much refactored the relevant code...try the new version and let me know if it helped...
ps. if you can, please also run tests for signals, signals2 and program_options (these sometimes caught what the dedicated ones did not)...
r66407 has the correct pass/failed-as-expected results on VisualAge. All three test suites of program_options, signals and signals2 pass. I ran the same three suites on Sun as well, just to cover all bases. On 5.10, signals and signals2 pass completely, except for the usual spurious mutex_test failure as indicated in the regression matrix. program_options on 5.9 fails to compile parsers.o in a similar manner to the one reported in the regular trunk test matrix, so it's most probably not a Function fault (log attached). Hooray! -- Lars Viklund | zao@acc.umu.se

"Lars Viklund" <zao@acc.umu.se> wrote in message news:20101105230105.GA24771@hatchepsut.acc.umu.se...
r66407 has the correct pass/failed-as-expected results on VisualAge. All three test suites of program_options, signals and signals2 pass.
I ran the same three suites on Sun as well, just to cover all bases.
On 5.10, signals and signals2 pass completely, except for the usual spurious mutex_test failure as indicated in the regression matrix.
program_options on 5.9 fails to compile parsers.o in a similar manner to the one reported in the regular trunk test matrix, so it's most probably not a Function fault (log attached).
Hooray!
Great! :-) If you are interested and have a project with relatively significant boost::function usage I'd love to hear your results...the same advice/hints I gave to Hartmut apply... Additionally, if you would like to squeeze a little extra out of your compilers you might want to provide the appropriate sections in the detail/platform_specifics.hpp file ;) ps. do you perhaps know where is the list of compilers officially supported by Boost (I know I've seen it but can't remember the location)..? -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

<...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

"Hartmut Kaiser" <hartmut.kaiser@gmail.com> wrote in message news:00b201cb7857$9a5d1330$cf173990$@gmail.com...
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: ...snip... 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).
Hi, thank you very much for testing and providing such good feedback! You are completely right in detecting and identifying the culprit...This is a new issue inherent to implementations that use on-empty handlers/targets instead of the if-empty-then checks. I've fixed my implementation which you can grab again from the sandbox (the vault still has the old one). The new implementation has only slightly more expensive (public) empty() and (private, rarely used) vtable::move calls but it should now work even in the across-shared-modules-boundaries use case you described. I ran regression tests with VC10 and now all of them pass cleanly, i.e. the assertions in Program Options are gone...and thanks to your feedback now I know what caused them...the tests used DLLs (causing exactly the behaviour you described) when run by the automated regression tests procedure and did not use them when run straight from the IDE...so once again thanks for very useful feedback ;-) ps. I hope I did not break anything for other compilers...did not have the time now to run tests for them also...
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).
Shouldn't the same hold for .dynlibs and .sos? -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

"Hartmut Kaiser" <hartmut.kaiser@gmail.com> wrote in message news:00b201cb7857$9a5d1330$cf173990$@gmail.com...
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: ...snip... 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).
Hi, thank you very much for testing and providing such good feedback! You are completely right in detecting and identifying the culprit...This is a new issue inherent to implementations that use on-empty handlers/targets instead of the if-empty-then checks. I've fixed my implementation which you can grab again from the sandbox (the vault still has the old one). The new implementation has only slightly more expensive (public) empty() and (private, rarely used) vtable::move calls but it should now work even in the across-shared- modules-boundaries use case you described. I ran regression tests with VC10 and now all of them pass cleanly, i.e. the assertions in Program Options are gone...and thanks to your feedback now I know what caused them...the tests used DLLs (causing exactly the behaviour you described) when run by the automated regression tests procedure and did not use them when run straight from the IDE...so once again thanks for very useful feedback ;-)
ps. I hope I did not break anything for other compilers...did not have the time now to run tests for them also...
Thanks for the fix! Everything seems to work now (VS2010, 64 bit, I have not tried any other compiler, though). Great news.
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).
Shouldn't the same hold for .dynlibs and .sos?
That depends on the system. I believe on Linux (.so) it would have worked. Regards Hartmut --------------- http://boost-spirit.com
-- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi, thank you very much for testing and providing such good feedback! You are completely right in detecting and identifying the culprit...This is a new issue inherent to implementations that use on-empty handlers/targets instead of the if-empty-then checks. I've fixed my implementation which you can grab again from the sandbox (the vault still has the old one). The new implementation has only slightly more expensive (public) empty() and (private, rarely used) vtable::move calls but it should now work even in the across-shared- modules-boundaries use case you described. I ran regression tests with VC10 and now all of them pass cleanly, i.e. the assertions in Program Options are gone...and thanks to your feedback now I know what caused them...the tests used DLLs (causing exactly the behaviour you described) when run by the automated regression tests procedure and did not use them when run straight from the IDE...so once again thanks for very useful feedback ;-)
ps. I hope I did not break anything for other compilers...did not have the time now to run tests for them also...
Thanks for the fix! Everything seems to work now (VS2010, 64 bit, I have not tried any other compiler, though). Great news.
I have to correct myself. While it seems to run fine in release mode, I'm now seeing an assertion in debug mode at function_template.hpp, line 579. I have no idea what this means. Regards Hartmut --------------- http://boost-spirit.com

"Hartmut Kaiser" <hartmut.kaiser@gmail.com> wrote in message news:015c01cb7968$cfbf46d0$6f3dd470$@gmail.com...
I have to correct myself. While it seems to run fine in release mode, I'm now seeing an assertion in debug mode at function_template.hpp, line 579. I have no idea what this means.
Hi, thanks for reporting back again... Even though I was unable to reproduce the problem I know what's the cause...I'm sorry, "the hour was late" and I made an incorrect function alignment assumption in my last change (which what the assertion caught)...you can grab the fixed version from the sandbox...the small added overheads mentioned in the last post are also gone ;) This time I also ran regression tests in 64 bit mode... ps. even though I switched to a different implementation I would like to be able to reproduce the behaviour with the old one (maybe for a new test)...so if your use case is easily converted into sample code (i.e. w/o proprietary or 'closed code') I'll be more than happy to give it a spin ;)
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).
Shouldn't the same hold for .dynlibs and .sos?
That depends on the system. I believe on Linux (.so) it would have worked.
Hmm, I obviously don't know much about the Linux DSO architecture, but 'at the bottom' DSO's are just that, 'dynamic shared objects', each of which must have its own static vtable copy so it is not quite obvious to me how could it work then...? -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

At Mon, 1 Nov 2010 14:34:08 +0100, Domagoj Saric wrote:
Hmm, I obviously don't know much about the Linux DSO architecture, but 'at the bottom' DSO's are just that, 'dynamic shared objects', each of which must have its own static vtable copy so it is not quite obvious to me how could it work then...?
Fixups are applied at load time if the symbol is already loaded into the executable image. Of course, all this depends on how the DSO is loaded. See http://gcc.gnu.org/ml/gcc/2002-05/msg01970.html for relevant details. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

"David Abrahams" <dave@boostpro.com> wrote in message news:m2y69dghpa.wl%dave@boostpro.com...
At Mon, 1 Nov 2010 14:34:08 +0100, Domagoj Saric wrote:
Hmm, I obviously don't know much about the Linux DSO architecture, but 'at the bottom' DSO's are just that, 'dynamic shared objects', each of which must have its own static vtable copy so it is not quite obvious to me how could it work then...?
Fixups are applied at load time if the symbol is already loaded into the executable image. Of course, all this depends on how the DSO is loaded. See http://gcc.gnu.org/ml/gcc/2002-05/msg01970.html for relevant details.
I understand, thanks for the link :) But, wouldn't this require for the symbol in question to be exported (not something one would want for an uber-mangled piece of boost::function<> bowels)? -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

I have no idea what this means.
I have to correct myself. While it seems to run fine in release mode, I'm now seeing an assertion in debug mode at function_template.hpp, line
Hi, thanks for reporting back again... Even though I was unable to reproduce the problem I know what's the cause...I'm sorry, "the hour was late" and I made an incorrect function alignment assumption in my last change (which what the assertion caught)...you can grab the fixed version from the sandbox...the small added overheads mentioned in the last post are also gone ;) This time I also ran regression tests in 64 bit mode...
Yep, that fixes the assertion. Thanks a lot. I'll do some performance comparisons later.
ps. even though I switched to a different implementation I would like to be able to reproduce the behaviour with the old one (maybe for a new test)...so if your use case is easily converted into sample code (i.e. w/o proprietary or 'closed code') I'll be more than happy to give it a spin ;)
The assertion fired during the construction of the first non-empty function object. So it should be easy to reproduce. Regards Hartmut --------------- http://boost-spirit.com

"Hartmut Kaiser" <hartmut.kaiser@gmail.com> wrote in message news:01d101cb79de$43ce5f50$cb6b1df0$@gmail.com...
Yep, that fixes the assertion. Thanks a lot. I'll do some performance comparisons later.
If you want, you can also play with some of the new features. I already mentioned the 'compile-time' assign() overloads (not really necessary for a 0x lambda enabled compiler like VC10). If you do not need the runtime type introspection functionality, try BOOST_FUNCTION_NO_RTTI (for me, in a project with lots of meta-template-programming generated targets, this resulted in the largest binary size reduction)...of course, be careful about the ODR if you use it... If you do not rely on the throw-on-empty behaviour you can use a different on-empty-handler. For boost::functions<> to which you only assign targets that you know are nothrow you can also set the is_no_throw policy to true (in x64 mode for MSVC this only has possible binary size reduction benefits, unlike in x86 mode where it also has possible runtime speed benefits)... You use policies like this: typedef boost::mpl::map2 < boost::mpl::pair<boost::empty_handler_t, boost::assert_on_empty>, boost::mpl::pair<boost::is_no_throw_t , boost::mpl::true_ >
my_bf_policies;
boost::function<int(int), my_bf_policies> my_bf; You don't need to specify all policies, the one(s) you do not mention are defaulted... ps. I developed a kind of 'release-mode link-time' 'is-it-really-a-nothrow-function' system that will reject (invoking the empty-handler) at runtime any target not detected as nothrow that was tried to be assigned to a b.function marked as nothrow...(it will obviously reject all function pointer targets as such 'optimizer introspection' does not work with indirect calls)...This was tested to work in 32 bit release mode with MSVC (8, 9 and 10)...unfortunately it does not seem to work in x64 mode (it seems there was a serious regression in the MSVC optimizer in that mode)... Anyways I've just changed this so that this check is skipped (and the assign automatically/always performed) for all unsupported/untested platforms (making it the user's responsibility to make sure what targets it tries to assign...)...
The assertion fired during the construction of the first non-empty function object. So it should be easy to reproduce.
I could not reproduce this...considering it is/was a function alignment issue I'd say the crucial part is the type of target you tried to assign (because the generated 'back-side' code directly depends on this)... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

"Domagoj Saric" <dsaritz@gmail.com> wrote in message news:iand2f$2na$1@dough.gmane.org...
...this resulted in the largest binary size reduction...
Speaking of binary size, if you have not already run your testing you might want to update, I've refactored the (copy) construction and destruction code to avoid creating unnecessary EH states (and related bloat). With the new code, bjam variant=release link=shared runtime-link=shared signals gives: - gcc 4.0.1: sizeof( libboost_signals.dylib, official b.function ) = 126.076 bytes sizeof( libboost_signals.dylib, new b.function ) = 109.676 bytes - clang 2.8 sizeof( libboost_signals.dylib, official b.function ) = 98.960 bytes sizeof( libboost_signals.dylib, new b.function ) = 85.604 bytes That's about 15% less with a simple recompilation...also note that (as far as I could tell from skimming through signals source), boost::signals use only a single boost::function instantiation... ps. When it comes to binary size MSVC is still way ahead of the GNU tools, producing a DLL half the size of the Clang 2.8 result and the difference between the old and new function builds is very small with VC10... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Domagoj, Do you plan to use variadic templates when they are available from the compiler? In case you aren't already aware, there is also a version of Boost.Function in the sandbox that supports a variadic template implementation, which you might be able to suck some code out of for your version: https://svn.boost.org/trac/boost/browser/sandbox/boost0x/boost/function -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkzRzaIACgkQ5vihyNWuA4UvTwCgkhFfUnhDnXNE6xp4UPTe48TV ZycAn1FhtOREhJDGmC+OXIOrXItEQUoj =724H -----END PGP SIGNATURE-----

"Frank Mori Hess" <frank.hess@nist.gov> wrote in message news:201011031701.22401.frank.hess@nist.gov...
Do you plan to use variadic templates when they are available from the compiler? In case you aren't already aware, there is also a version of Boost.Function in the sandbox that supports a variadic template implementation, which you might be able to suck some code out of for your version:
https://svn.boost.org/trac/boost/browser/sandbox/boost0x/boost/function
Hi, thanks for the link...I wasn't aware of this side-development... In any case, I'd certainly want variadic template support. However, considering that my knowledge of the subject is mostly purely informational and that, for such a low level library, supporting old(er) and/or deficient, but still used, compilers is a higher priority this will have to wait...probably until MSVC++ finally implements variadic templates... But if you or someone else is willing to join/help they are more than welcome... -- "What Huxley teaches is that in the age of advanced technology, spiritual devastation is more likely to come from an enemy with a smiling face than from one whose countenance exudes suspicion and hate." Neil Postman
participants (7)
-
David Abrahams
-
Domagoj Saric
-
Domagoj Saric
-
Frank Mori Hess
-
Hartmut Kaiser
-
Lars Viklund
-
Sebastian Redl