scitools.com

← Graph catalog

Variable Tracker is one of the interactive graphs Understand can draw of your code — call trees, dependencies, control flow, and more.

Variable Tracker

Languages: C#, C++, Java
Targets: Objects
Variants: Classic

Show the source code of everything a selected object, variable, or parameter's value is directly or indirectly built from.

For a selected object, variable, or parameter, this shows the source code of each place that sets its value — an assignment, an increment or decrement, or an argument passed to a function's parameter — then recurses into every entity that appears in that code, building a multi-level tree. When a value comes from a function call, this continues into the called function's own return statements; when a value comes from a parameter, this continues into the argument passed at each call site.

See the Assignments graph for a related view of the same relationships. Assignments uses "assign" references and shows just the entities involved, so it skips over literals. Variable Tracker instead shows the actual source code at each step, following every entity that appears in it. That leads to a slight difference in code like x = func(y). Both graphs connect x to func(), using the function's return statements, but the Variable Tracker will additionally connect y because it's part of the same statement. Both graphs can follow assignments to a parameter from each call site.

Rooted at demoObject in myFunction below, the graph shows its direct inputs: x, plusEqualsObject, and the literal-only assignments demoObject = 0 and demoObject++ (shown with no further inputs of their own), plus its two calls to demoFunction. Since both calls reach the same demoFunction entity, it's shown once, expanding into each of its own return statements — including return demoParameter, which in turn is fed by whatever was passed at each call site, x and indirectObject + 1.

See the following code and corresponding graph

extern int directFunction();
extern int indirectFunction();
extern int indirectObject;
extern int plusEqualsObject;

int demoFunction(int demoParameter)
{
  switch (demoParameter) {
    case 0: return demoParameter; // demoParameter -> demoFunction()
    case 1: return directFunction(); // -> demoFunction()
    case 2: return 0; // literal, no reference
    default:
      // All indirect: part of an expression
      return indirectObject + // indirectObject -> demoFunction()
             indirectFunction() + // -> demoFunction()
             1; // literal, no reference
  }
}

void myFunction(int x)
{
  // demoFunction() -> demoObject; x -> demoParameter
  int demoObject = demoFunction(x);

  demoObject = x; // x -> demoObject
  demoObject = 0; // literal, no reference

  // All indirect: part of an expression
  demoObject = indirectObject + // indirectObject -> demoObject
               // demoFunction() -> demoObject; x -> demoParameter
               demoFunction(indirectObject + 1) +
               1; //  literal, no reference

  demoObject ++; // modification by literal, no reference

  // modification by plusEqualsObject, indirect assignment
  demoObject += plusEqualsObject;
}