Я преподаю курс программирования, где мы будем использовать C++. Я собираю раздаточный материал о том, как использовать отладчик и хотел, чтобы студенты пошагового выполнения этого генератора кода хэш-именами и фамилиями:Продолжение в цикле, основанном на диапазоне, не регрессирует точки останова?
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;
}
Использование GDB, я поставил точку останова на строке, содержащей диапазон основе для цикла:
(*) for (char ch: first + last)
Когда я запускал программу с помощью GDB, как и ожидалось, что вызвало точку останова здесь. Однако, если я продолжу выполнение, точка останова не перезагружается, и программа завершается.
Я могу последовательно воспроизвести это поведение в своей системе. Если я устанавливаю точку останова внутри тела цикла и запускаю ее до тех пор, пока она не будет удалена, если я затем добавлю точку останова в верхнюю часть цикла и нажму «продолжить», отладчик пропустит точку останова цикла.
Я предполагаю, что это, вероятно, потому, что цикл на основе диапазона расширяется в ряд различных этапов инициализации (я могу фактически видеть временные переменные, которые были сгенерированы в моем окне отладки), и точка останова устанавливается на шаг инициализации, а не шаг цикла. Если это так, это понятно, но удивительно противоречиво.
Мое текущее решение этой проблемы заключается в том, чтобы установить точку останова в первом выражении внутри цикла, а не в верхней части цикла, но это противоречит интуиции и, с педагогической точки зрения, очень плохой совет в будущем.
Мои вопросы следующие:
- Является ли мой анализ правильно?
- Является ли это специфическим для моей версии gdb? Я использую
- Ubuntu 16.04 и
- г ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) 5.4.0 20160609. имеют
- Есть ли способ, чтобы получить GDB для обрабатывать точку останова в цикле, основанном на диапазоне, как точку останова на теле цикла, а не на этапе инициализации?
«Является ли эта ОС или Qt Creator конкретной версией?» Это может быть причуда GDB, вы можете попробовать это с помощью Visual C++ и/или Clang и посмотреть, получится ли у вас тот же результат. В конце концов, отладчик Qt Creator является графическим интерфейсом. – MrEricSir
@MrEricSir Хороший звонок! Оказывается, это проблема GDB! Я не могу найти ничего об этом с помощью некоторых поисков Google, поэтому я обновил вопрос, чтобы переориентировать его. – templatetypedef
Для отладки производства можно переключиться на вид ассемблера, а затем установить контрольную точку на итерационной части кода. Однако я подозреваю, что «переключиться на вид ассемблера» - это, вероятно, не первая вещь, которую нужно учить! –