Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Debugging C++ public member variable modifications / accesses

3.66/5 (11 votes)
20 Nov 20063 min read 1  
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 ...

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

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

C++
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

C++
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