Difficulty: Easy · Puzzle 6 of 6 · Topic: Virtual Method Puzzles
A derived override calls `super.report()`. Predict final string and explain call chain.
class base_r;
virtual function string report();
return "B";
endfunction
endclass
class mid_r extends base_r;
function string report();
return {"M-", super.report()};
endfunction
endclass
class ext_r extends mid_r;
function string report();
return {"E-", super.report()};
endfunction
endclass
initial begin
base_r h;
ext_r e;
e = new();
h = e;
$display("%s", h.report());
end`super` is lexical (next class in inheritance chain), not dynamic back to most-derived.
1) Dynamic dispatch picks `ext_r::report` for `h.report()`.
2) `ext_r` calls `super.report()` => `mid_r::report`.
3) `mid_r` calls its `super.report()` => `base_r::report`.
4) Concatenation yields `E-M-B`.Answer: Final output is `E-M-B`; dynamic entry is most-derived, then explicit `super` walks up one lexical level each call.
Checked by running the code in Verilator 5; the printed output supports the answer above. The shown code run in Verilator: each super.report() walks one level up the chain.
`super.report()` is a lexical call to the parent class's implementation, never a new dynamic dispatch, so it cannot loop back to `ext_r`. Candidates who think it re-dispatches expect infinite recursion.
How would behavior change if `mid_r::report` were declared non-virtual? Model answer: it would not change. Once a method is virtual in the base, every same-prototype method in a derived class is virtual whether or not the keyword is repeated, so the output is still `E-M-B`. (Verified in Verilator.)
The output is E-M-B. The call dispatches dynamically to the most derived report. Then each level calls super, which walks up exactly one level at a time, from extended to mid to base. The trap is thinking super skips to the base directly. I would check that every level really calls super and that report is virtual.