I'm teaching a programming course where we'll be using C++. I was putting together a handout about how to use the debugger and wanted to have students step through the execution of this hash code generator for first and last names:
int nameHash(string first, string last){
/* This hashing scheme needs two prime numbers, a large prime and a small
* prime. These numbers were chosen because their product is less than
* 2^31 - kLargePrime - 1.
*/
static const int kLargePrime = 16908799;
static const int kSmallPrime = 127;
int hashVal = 0;
/* Iterate across all the characters in the first name, then the last
* name, updating the hash at each step.
*/
for (char ch: first + last) {
/* Convert the input character to lower case, then make sure it's
* between 0 and the small prime, inclusive.
*/
ch = tolower(ch) % (kSmallPrime + 1);
hashVal = (kSmallPrime * hashVal + ch) % kLargePrime;
}
return hashVal;
}
Using gdb, I set a breakpoint on the line containing the range-based for loop:
(*) for (char ch: first + last)
When I ran the program with gdb and as expected it triggered a breakpoint here. However, if I then continue execution, the breakpoint does not retrigger and the program runs to completion.
I can reproduce this behavior consistently on my system. If I set a breakpoint inside the body of the loop and run until it's hit, if I then add a breakpoint at the top of the loop and hit "continue" the debugger will skip over the loop breakpoint.
I assume that this is probably because a range-based for loop expands out into a series of different initialization steps (I can actually see the temporary variables that were generated in my debug window) and the breakpoint is getting set on the initialization step rather than the loop step. If that's the case, it's understandable but surprisingly counterintuitive.
My current workaround for this issue is to set a breakpoint at the first statement inside the loop rather than at the top of the loop, but this is counterintuitive and, from a pedagogical perspective, really bad advice going forward.
My questions are the following:
You're expecting a one-to-one mapping of source code and execution that doesn't quite exist. The for line isn't "repeated" on each loop iteration; it only introduces and describes how the loop will operate.
It is expected behaviour that a breakpoint on the for line will only be hit once. I don't recall ever using a C, C++, JavaScript, whatever debugger that worked differently.
Put your breakpoint on the first line of the body, instead; it is the body that is repeated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With