Click here to Skip to main content
Licence 
First Posted 20 Nov 2006
Views 16,636
Bookmarked 11 times

Debugging C++ public member variable modifications / accesses

By | 20 Nov 2006 | Article
A trick to use operator overloading to debug the public member variable modifications / accesses

Introduction

In a lot many C++ maintenance / enhancement projects, public member variables are a reality, specially when these projects are converted from C to C++. In these projects, one issue which I faced constantly while debugging is where and how to set a breakpoint in order to find out when a certain public member variable gets modified or is being accessed. These member variables are typically of the basic C, C++ types like int, double etc. The common reason to end up in this situation is due to the promotion of the C structs to C++ classes without any accessor or modifier methods, it mostly happens during the C to C++ migration, in order to speed up the project or sometimes because some lazy colleague takes a short cut with public member variables.

Why is it so frustrating?

It's so frustrating to see the same member variable name being used in 10 different classes and then those 10 different classes are being used in 100 different files. And when you search for that variable you get 1000 hits and you keep wondering which one of these is the right place where my instance of the class is getting modified. Consider yourself lucky if you are facing this kind of trouble routinely.

What are my options while debugging?

There are certain solutions available for this problem in Visual Studio debugger. The favorite one is to set a breakpoint when the member variable gets modified. This solution works well in most of the cases. But there is a limitation - the breakpoint has to be set at runtime for the modification in the context of the instance of the class and you have to know the flow of execution well in order to get the right instance. When you have a lot of instances of the class you don't know which particular class is really of your interest. You will have to sweat a lot before setting the breakpoint in the right context or in the worst case you don't know the flow of the execution and won't be able to find any context of your interest.

Anyway, there is no way to set a breakpoint to check when a member variable is being accessed.

The 'Problem Code'

Let's see how the code looks for the debugging issue which I am talking about ...

class RequestA
{
public:
    //Other member variables
    int v1;
    int v2;
    //member variable of our interest
    int status;
};

class RequestB
{
public:
    //Other member variables
    int v3;
    int v4;
    //member variable of our interest
    int status;
};

void UserFunction1(int condition)
{
    RequestA reqA1;
    RequestA reqA2;
    RequestB reqB1;
    RequestB reqB2;

    reqA1.status = 0;
    reqA2.status = reqA1.status;
    reqB1.status = reqA1.status;
    if (reqB1.status == 0)
    {
        reqB2.status = reqB1.status;
    }
    
    switch(condition)
    {
    case 10:
        //Some code            
        //
        //
        //
        reqA2.status = 0;
        //some other processing
        //
        reqB1.status = 0;
        //Some code
        //
        //
        //
        reqA1.status = 2;
    case 11:
        reqA1.status = 3;
        //Some code
        //
        //
        //
        reqA2.status = 0;
        //Some code
        //
        //
        //
        reqB1.status = 0;
    case 16:
        reqA1.status = 3;
        //Some code
        //
        //
        //
        reqB2.status = 4;
        //Some code
        //
        //
        //
    case 19:
        reqA1.status = 5;
        //Some code
        //
        //
        //
        reqA1.status = 3;
        reqB1.status = 3;
    }
}

void UserFunction2(int anotherCondition)
{
    RequestA reqA1;
    RequestA reqA2;
    RequestB reqB1;
    RequestB reqB2;
    reqA1.status = 1;
    reqA2.status = 2;
    reqB1.status = 3;
    reqB2.status = 4;
    //Some complex and long algorithm modifying status variable
    //...
    //...
    reqA1.status = reqA2.status;
    reqA2.status = reqB1.status ;
    reqB1.status = reqB2.status ;
    reqB2.status = reqA2.status;
}

My solution to set the breakpoint for modifications or accesses

In this context, I find the following simple C++ trick is very useful to catch the code which modifies the public variables. I define a wrapper class around the basic int, let's call it BasicIntWrapper. It provides the operators necessary to extract int value and assign it back.

class BasicIntWrapper
{
    int m_i;
public:
    operator int()
    {
        return m_i;
    }
    int operator = (const int& value)
    {
        return (m_i = value);
    }
    //Some more additional operators as needed..
    //...
    //...
    //...
};

Now for the debug build let's refine the class member status as BasicIntWrapper status; Let's see the redefined class RequestB.

class RequestB
{
public:
    //Other member variables
    int v3;
    int v4;
    //member variable of our interest
#ifdef _DEBUG
    BasicIntWrapper status;
#else
    int status;
#endif
};

An even better approach will be to define this wrapper class as a member class of RequestB. This helps in 2 ways:

  1. Catches the modifications per class
  2. Takes care of name conflicts

class RequestB
{
public:
    //Other member variables
    int v3;
    int v4;
    //member variable of our interest
#ifdef _DEBUG
    class BasicIntWrapper
    {
        int m_i;
    public:
        operator int()
        {
            return m_i;
        }
        int operator = (const int& value)
        {
            return (m_i = value);
        }
        //Some more additional operators as needed..
        //...
        //...
        //...
    };
    BasicIntWrapper status;
#else
    int status;
#endif
};

Now, if you set a breakpoint in the operators of the class BasicIntWrapper, you get all the class wide modifications caught.

Final Comments

My experience is - There is no silver bullet for this issue, but this trick helps refining a breakpoint location to a great extent, before using the break points in Visual Studio.

Author: Vishal Jadhav
email : vishalya@yahoo.com

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Vishal B Jadhav

Web Developer

United States United States

Member

I have been working in the s/w industry for last 10 yrs, performing various roles as a developer/designer/QA analyst/team lead mostly on Microsoft technologies, C++. MFC, ATL and C# / .Net . I have worked on some development projects and a lot many maintenance projects during these years.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralYou can automate this even more... PinmemberJason King9:32 1 Dec '06  
GeneralImprove - not automate... PinmemberJason King9:36 1 Dec '06  
GeneralThat's why using accessors is better PinmemberMichal Blazejczyk5:22 28 Nov '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 20 Nov 2006
Article Copyright 2006 by Vishal B Jadhav
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid