473,395 Members | 1,996 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

MSVC 2003: ctor-try-block error: possible compiler bug

This message was originally posted to comp.lang.c++.moderated
----------------------------------------------------------------------------------------------

Hi!

I face a problem in my production code. I could deduce this problem to
program shown below. It seems, that try-block in constructor doesnt
work as it should (compared to case where no try block exists at all).
I tested this small program on my MSVC .NET Pro 2003 (and separately on
PC with MSVC2003 SP1 installed). In both cases I experienced the same
behaviour - access violation. Please see comment inside the program
body. To get this sample work - just comment out try block in ctor.

Have anyone faced such behaviour before? Is there known workarounds?
Thanks.
----
// ref_count.cpp : ctor try block invalid behaviour test

// if ctor uses try block (X::X), program crashes, trying to
dereferencing danglig pointer
// If try block is disabled, everything goes fine.

// I experienced this problem in my production code which used
boost::intrusive_ptr class.
// I wrote similar class (CountingPtr) for simplicty's sake (and to
kill dependencies) and results are the same - program crashes

// tested on compilers: MS VS.NET 2003 (both original & SP1)

#include <iostream>
#include <cassert>

using namespace std;

struct IRefCounted
{
virtual void addRef() = 0;
virtual void release() = 0;

virtual ~IRefCounted() {};
};

struct ILogger : public IRefCounted
{
void virtual write(const char * text) = 0;
};

class Logger : public ILogger
{
int m_ref;
~Logger(){}
public:
Logger() : m_ref(0)
{
}

void addRef()
{
m_ref++;
}

void release()
{
if(--m_ref == 0)
delete this;
}

void write(const char * text)
{
cout << text << endl;
}
};

template<typename T>
class CountingPtr
{
T * m_t;

public:
CountingPtr(T * t, bool addRef = true) : m_t(t)
{
assert(t!=0);
if(addRef)
t->addRef();
}

~CountingPtr()
{
if(m_t)
m_t->release();
}

CountingPtr&operator=(const CountingPtr & rhs)
{
if(this == &rhs)
assert(false);
else
{
m_t = rhs.m_t;
m_t->addRef();

}
return *this;
}

T * operator->()
{
return m_t;
}

CountingPtr(const CountingPtr & rhs)
{
*this = rhs;
}
};

typedef CountingPtr<ILoggerCLoggerPtr;
void use(CLoggerPtr logger)
{
logger->write("use");
}

class Loggable
{
public:
Loggable(CLoggerPtr logger) : m_logger(logger)
{}

private:
CLoggerPtr m_logger;
};

class X : public Loggable
{
public:
X(CLoggerPtr logger)
try : Loggable(logger) // comment try block out to
get working code!
{}
catch(std::runtime_error & )
{
throw;
};
};

int main(int argc, char* argv[])
{
try
{
CLoggerPtr logger(new Logger());
use(logger);

{
X y1(logger); // THIS line decrements ref counter by 2 in case try
block is active
}

{
X y2(logger); // OOPS IS HERE! If try block is in act, program tries
to reference dangling pointer
}

return 0;
}
catch(exception & ex)
{
cout << "Exception: " << ex.what() << endl;
return EXIT_FAILURE;
}
catch(...)
{
cout << "(...) exception" << endl;
return EXIT_FAILURE;
}
}

Sep 26 '06 #1
4 1977
ks***********@yandex.ru wrote:
This message was originally posted to comp.lang.c++.moderated
----------------------------------------------------------------------------------------------

Hi!

I face a problem in my production code. I could deduce this problem to
program shown below. It seems, that try-block in constructor doesnt
work as it should (compared to case where no try block exists at all).
I tested this small program on my MSVC .NET Pro 2003 (and separately on
PC with MSVC2003 SP1 installed). In both cases I experienced the same
behaviour - access violation. Please see comment inside the program
body. To get this sample work - just comment out try block in ctor.

Have anyone faced such behaviour before? Is there known workarounds?
Thanks.
----
// ref_count.cpp : ctor try block invalid behaviour test

// if ctor uses try block (X::X), program crashes, trying to
dereferencing danglig pointer
// If try block is disabled, everything goes fine.

// I experienced this problem in my production code which used
boost::intrusive_ptr class.
// I wrote similar class (CountingPtr) for simplicty's sake (and to
kill dependencies) and results are the same - program crashes

// tested on compilers: MS VS.NET 2003 (both original & SP1)

#include <iostream>
#include <cassert>

using namespace std;

struct IRefCounted
{
virtual void addRef() = 0;
virtual void release() = 0;

virtual ~IRefCounted() {};
};

struct ILogger : public IRefCounted
{
void virtual write(const char * text) = 0;
};

class Logger : public ILogger
{
int m_ref;
~Logger(){}
public:
Logger() : m_ref(0)
{
}

void addRef()
{
m_ref++;
}

void release()
{
if(--m_ref == 0)
delete this;
}

void write(const char * text)
{
cout << text << endl;
}
};

template<typename T>
class CountingPtr
{
T * m_t;

public:
CountingPtr(T * t, bool addRef = true) : m_t(t)
{
assert(t!=0);
if(addRef)
t->addRef();
}

~CountingPtr()
{
if(m_t)
m_t->release();
}

CountingPtr&operator=(const CountingPtr & rhs)
{
if(this == &rhs)
assert(false);
else
{
m_t = rhs.m_t;
m_t->addRef();

}
return *this;
}

T * operator->()
{
return m_t;
}

CountingPtr(const CountingPtr & rhs)
{
*this = rhs;
}
};

typedef CountingPtr<ILoggerCLoggerPtr;
void use(CLoggerPtr logger)
{
logger->write("use");
}

class Loggable
{
public:
Loggable(CLoggerPtr logger) : m_logger(logger)
{}

private:
CLoggerPtr m_logger;
};

class X : public Loggable
{
public:
X(CLoggerPtr logger)
try : Loggable(logger) // comment try block out to
get working code!
{}
catch(std::runtime_error & )
{
throw;
};
};

int main(int argc, char* argv[])
{
try
{
CLoggerPtr logger(new Logger());
use(logger);

{
X y1(logger); // THIS line decrements ref counter by 2 in case try
block is active
}

{
X y2(logger); // OOPS IS HERE! If try block is in act, program tries
to reference dangling pointer
}

return 0;
}
catch(exception & ex)
{
cout << "Exception: " << ex.what() << endl;
return EXIT_FAILURE;
}
catch(...)
{
cout << "(...) exception" << endl;
return EXIT_FAILURE;
}
}
This code (with the try block) works fine with g++. It even passes a
valgrind check. Maybe, you are better of in a compiler specific news group.
Also, you might consider submitting a bug report to your compiler vendor.
Best

Kai-Uwe Bux
Sep 26 '06 #2
Thanks,

Could someone recommend me alive group related to MS VC++ compiler?

Thanks,
Kirill

Sep 27 '06 #3
ks***********@yandex.ru wrote:
Thanks,

Could someone recommend me alive group related to MS VC++ compiler?

Thanks,
Kirill
http://www.parashift.com/c++-faq-lit...t.html#faq-5.9
Sep 27 '06 #4
Hi!

This discusion is mode here -
http://groups.google.com/group/comp....b4bc995e3975e6

Regards,
Kirill

Sep 27 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Manfred Eckschlager | last post by:
Hi, In Linux C++ there was an easy way to build a stream form a socket like: int sockFd = socket(AF_INET,SOCK_STREAM,0); filebuf *netBuf = new filebuf( sockFd ); -and then iostream...
0
by: 3doutpost | last post by:
(apologies for the new thread - for some reason google news doesn't give me the option to reply to an earlier vcbuild.exe thread) I'm trying to build a C++ project that was originally created in...
2
by: SpaceDust | last post by:
I am developing in MSVC++ .Net 2003, using MFC, building a realtime telemetry display. I have reached an object limit of 255, but need to add another 20+ objects. Is there a simple way to increase...
8
by: Chris Stankevitz | last post by:
I can't tell you how frusterated I and my coworkers are with "MSVC 7.1 .net 2003" (what am I supposed to call this thing anyway?). Compiling and linking take twice as long with "MSVC 7.1 .net...
4
by: Airw0lf | last post by:
Hi all, would appreciate help with some trouble I'm having after using the Visual C++ 2005 Express Conversion Wizard on my Visual C++ .NET 2003 project. The wizard completed successfully with...
6
by: Chris Stankevitz | last post by:
At link time, MSVC determines some of my libraries are unused and doesn't link them into my exe. This undesirable feature causes problems when I employ the factory pattern. With the factory...
2
by: Edson Tadeu | last post by:
When using an external tool to build (e.g NMAKE), the output window now prepends '1>' in each line. Also, the errors and warnings are not appearing on the task list anymore (as opposed to MSVC...
5
by: peifeng_w | last post by:
Hi, try the following code with flag=0/1/2. #include<iostream> using namespace std; #define flag 2//option:0,1,2 class C {
29
by: Nindi | last post by:
I cannot get the following code to compile under MSVC 2003 or 2005. ........................................................................................... #include<stdio.h> struct...
17
by: fl | last post by:
Hi, I am learning C++ from the following C++ website, which has some very good small examples. For the second Fraction example, which has five files: Main.cpp Fraction.cpp Fraction.h...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.