$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-users] Microsoft compiler bug: Boost 1.38 smart pointers + CLI = crash
From: Oleg Golosovskiy (ogolosovskiy_at_[hidden])
Date: 2009-03-05 05:47:41
I have added a new bug to connect.microsoft.com. I can send the sample 
project if anybody needs it.
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=420897
Type 	Bug 	ID 	420897
Status 	Active 	Access Restriction 	Public
Opened By 	OlegGL 	Blocking Issue 	No
Opened 	3/5/2009 	Submission Language 	English
        
        
        
------------------------------------------------------------------------
*Description
*
The problem looks identical to one described in bug #101889. 
http://connect.microsoft.com/VisualStudio/feedback/Workaround.aspx?FeedbackID=101889
There is only one difference - intrusive_ptr instead of shared_ptr 
originally reported in #101889
The code bellow causes assertion:
    boost::intrusive_ptr<test_ptr> ptr;
    if(ptr)
        assert(false); //MUST NOT HAPPEN BUT IT DOES!
Reproduced on VS2005 SP1 and VS2008 SP1 (Windows XP SP2)
Boost 1.38
To reproduce the problem, the Boost (booost/smart_ptr.hpp in our case) 
shall be included in the CLI-compiled file under #pragma managed 
(push,off) (see the code below)
If changed to "#pragma managed (push,on)", then everything is fine
Product Language
English
Version
Visual Studio 2008 SP1
Operating System
Windows XP Professional
Operating System Language
English
*How to reproduce:
*Create any native win32 C++ project, for example a console based.
int _tmain(int argc, _TCHAR* argv[])
{
do_test();
return 0;
}
1) Install and compile BOOST 1.38
2) Add a new CPP file to the project.
This file has a minimal intrusive pointer "environment" and a code 
check. The Code is below.
3) Set /clr option for that particular file (Common Language Runtime 
Support in the Options)
4) build the project
#include "stdafx.h"
#include "test3_dll.h"
#pragma  managed (push,off)
#include "boost/smart_ptr.hpp"
class intrusive_ptr_base1
{
friend void intrusive_ptr_add_ref(intrusive_ptr_base1*);
friend void intrusive_ptr_release(intrusive_ptr_base1*);
size_t m_ref_counter;
void add_ref()
    {    ++m_ref_counter;    }
void release()
    {    if (--m_ref_counter == 0) delete this; }
protected:
    intrusive_ptr_base1() : m_ref_counter(0) {}
    virtual ~intrusive_ptr_base1() {}
    intrusive_ptr_base1(intrusive_ptr_base1 const &) :m_ref_counter(0) {}
    intrusive_ptr_base1 &operator=(intrusive_ptr_base1 const &)    {    
return *this;    }
};
inline void intrusive_ptr_add_ref(intrusive_ptr_base1* e)
    {    e->add_ref(); }
inline void intrusive_ptr_release(intrusive_ptr_base1* e)
    {    e->release(); }
class test_ptr : public intrusive_ptr_base1
{
};
#pragma  managed (pop)
void do_test()
{
    boost::intrusive_ptr<test_ptr> ptr;
    if(ptr)
        assert(false);
}
Actual Results
if(ptr) returns true for the empty ptr!
Expected Results
if(ptr) must return false for the empty ptr
TAP Code (if applicable)