Search code examples
c++visual-studio-debuggingpass-by-value

C++ / Pass by value results in #DEN


Debugging some code with Visual Studio and I was surprised to find that the values of the property of an object looked great before the call into a method and then were corrupted as soon as I entered the method:

The call comes from here. The debugger reports that thingA.property = 0.14

method1()
{
  Thing thingA;

  object.method2(thingA)
}

and goes into here and the debugger reports thingMine.property = 4.0E-315#DEN

method2(Thing thingMine)
{
....
}

When I change scope back up to method1 the property looks fine and scoping back down to method2 the property takes on a wildly different value.

What can cause the value to change? Back in the old days with C, I can mangle memory by fooling around with pointers. However, there's nothing fancy about this code. There are no (explicit) pointers. The compiler is happy with the cast / class of all the objects. There is no fancy inheritance or overloading.

To add more detail, Thing is not simply a class with properties and methods. Its properties are objects, but still not very fancy:

class Thing {
public:
  AnotherThing thingInsideAThing;
...
}

It is the property of AnotherThing that is getting mangled.

My understand of pass-by-value is based upon my ancient schooling in C. I thought calling a method would push an explicit copy of thingA onto the stack. Does it push a bad address for thingA.object onto the stack? I thought pass-by-value was always the safest way to forward information into a method.

Where do I begin to understand the underlying problem?


Solution

  • I believe the answer is found in the way that Visual Studio displays values for objects that are

    • pass by value
    • pass by constant reference

    The code below assigns the proper value to a. However, for my object, the debugger reports #DEN when I ask it to display thing.x.

    method(Thing thing)
      {
        double a = thing.x;
      }
    

    However, when I write:

    method(const Thing& thing)
      {
        double a = thing.x;
      }
    

    the debugger reports the expected value for thing.x.

    I recognize that there is a difference between pass by value and pass by constant reference. However, in my case I don't think that there is a practical difference.