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++, JavaTargets: 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;
}