   tr1::function buggy on MSVC9?
  I'm writing an example program to demonstrate function and bind to some other people, but pushing functions into a vector is causing crashes.In the past I've always used boost's implementation of these - for this example I'm using the ones from MSVC 2008 though.In the following example, there's 3 commented out lines where I manually set the size of the vector and use assignment to hard-coded indices -- if I use those lines instead of the equivalent push_back version, it works fine. Does anyone know why the push_back version would be crashing?The crash happens either when I try to call the functions in the vector, or if I disable that code, the crash happens when the vector goes out of scope.#include <functional>#include <algorithm>#include <vector>using namespace std;using namespace tr1;using namespace placeholders; void MyCallback(){  printf( " called MyCallback()\n" );}void MyCallback2( int number ){  printf( " called MyCallback2(%d)\n", number );}int main(int argc, char* argv[]){    printf( "events += MyCallback\n" );    printf( "events += MyCallback2, 42\n" );    //vector<function<void()>> events(2);    //events[0] = &MyCallback;    //events[1] = bind( &MyCallback2, 42 );    vector<function<void()>> events;    events.push_back( &MyCallback );    events.push_back( bind( &MyCallback2, 42 ) );    struct call { void operator()( const function<void()>& f ) { f();    }};    printf( "Calling foreach events\n" );    for_each( events.begin(), events.end(), call() );    printf( "\n" );    printf( "Press enter..." );    getchar();    return 0;}[Edited by - Hodgman on April 28, 2010 10:09:54 PM]
  Ok this keeps getting weirder... This example crashes too, but if I un-comment the call to reserve, then it works fine.int main(int argc, char* argv[]){    vector<function<void()>> events;    //events.reserve(2);    events.push_back( &MyCallback );    events.push_back( bind( &MyCallback2, 42 ) );    struct call    {   void operator()( const function<void()>& f )   {  f();   }    };    for_each( events.begin(), events.end(), call() );    return 0;}Something to do with reallocating the vector's internal buffer???AFAIK, reserve should never fix a crash! Unless I'm doing something really wrong...   ;  Are you using VS2008 RTM or SP1? I tried the second example with SP1 and everything worked as it should without the call to reserve().   ;  Thanks for testing it, though now I'm more worried if it works on some MSVC9 installs, and not others...Yeah I think SP1 is installed :/This is from help->aboutMicrosoft Visual Studio 2008 Version 9.0.30729.1 SPHotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB944899)   KB944899Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB945282)   KB945282Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB946040)   KB946040Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB946308)   KB946308Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB946344)   KB946344Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB946581)   KB946581Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB947171)   KB947171Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB947173)   KB947173Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB947180)   KB947180Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB947540)   KB947540Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB947789)   KB947789Hotfix for Microsoft Visual Studio 2008 Professional Edition - ENU (KB948127)   KB948127Microsoft Visual Studio 2008 Professional Edition - ENU Service Pack 1 (KB945140)   KB945140Microsoft Visual Studio 2008 Professional Edition - ENU Service Pack 1 (KB947888)   KB947888Microsoft Visual Studio 2008 Professional Edition - ENU Service Pack 1 (KB948484)   KB948484[EDIT]Here's my full source code that you can c&p into a new console application// TestTR1_2.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <functional>#include <algorithm>#include <vector>using namespace std;using namespace tr1;using namespace placeholders; void MyCallback(){  printf( " called MyCallback()\n" );}void MyCallback2( int number ){  printf( " called MyCallback2(%d)\n", number );}class Test{public:  Test() : member(1337) {}  int member;  void PrintNumbers( int number )  {    printf( " called Test::PrintNumbers(%d), member = %d\n", number, member );  }};int _tmain(int argc, _TCHAR* argv[]){  {    function<void()>    eventNoArgs;    printf( "eventNoArgs = MyCallback\n" );    eventNoArgs = &MyCallback;    printf( "Calling eventNoArgs()\n" );    eventNoArgs();    printf( "\n" );    printf( "eventNoArgs = MyCallback2, 42\n" );    eventNoArgs = bind( &MyCallback2, 42 );    printf( "Calling eventNoArgs()\n" );    eventNoArgs();    printf( "\n" );  }  {    function<void(int)> event1Arg;    Test object;    printf( "event1Arg = MyCallback\n" );    event1Arg = bind( &MyCallback );    printf( "Calling event1Arg(42)\n" );    event1Arg( 42 );    printf( "\n" );    printf( "event1Arg = MyCallback2, arg#1\n" );    event1Arg = bind( &MyCallback2, _1 );    printf( "Calling event1Arg(42)\n" );    event1Arg( 42 );    printf( "\n" );    printf( "event1Arg = Test::PrintNumbers, object, arg#1\n" );    event1Arg = bind( &Test::PrintNumbers, &object, _1 );    printf( "Calling event1Arg(42)\n" );    event1Arg( 42 );    printf( "\n" );  }  {    printf( "events += MyCallback\n" );    printf( "events += MyCallback2, 42\n" );    /*vector<function<void()>> events(2);    events[0] = &MyCallback;    events[1] = bind( &MyCallback2, 42 );*/    vector<function<void()>> events;    //events.reserve(2);    events.push_back( &MyCallback );    events.push_back( bind( &MyCallback2, 42 ) );    printf( "Calling foreach events\n" );    struct call { void operator()( const function<void()>& f ) { f(); }};    for_each( events.begin(), events.end(), call() );    printf( "\n" );  }  printf( "Press enter..." );  getchar();return 0;} [Edited by - Hodgman on April 29, 2010 12:59:37 AM];  Seems to work fine on my install of VS2008 here also but chokes on VS2010 with following error:Error1error C2872: 'placeholders' : ambiguous symbol;  The full code, pasted directly into a new project in my copy of VS2008, crashes on the for_each(). If I switch it to use Boost.Bind & Boost.Function (v1.36), without any other changes, it works fine.So yeah, it probably is an implementation bug. I don't have VS2010 to check with, unfortunately.   ;  I don't really know if this is related but I remember seeing this in a blog postfunction<FT>::swap() was broken by the Small Functor Optimization in VC9 TR1 (the Feature Pack).  This broke vector<function<FT>> in VC9 SP1.  "Broken" meant "compiling but crashing".http://blogs.msdn.com/vcblog/archive/2008/12/17/vc9-sp1-hotfix-for-the-vector-function-ft-crash.aspx   ;  Hah i was going to post that but someone beat me to it :)   ;  Thanks for the info guys. Guess I should just stick to the boost versions for now, as I can be sure they'll work on everyone's installation ;)   