저는 C++을 사용할 프로그래밍 코스를 가르치고 있습니다. 내가 디버거를 사용하는 방법에 대한 유인물을 함께 넣고 학생들은 이름과 성이 해시 코드 생성기의 실행을 통해 단계가 싶었다 :범위 기반 for 루프에서 계속하면 중단 점을 다시 트리거하지 않습니까?
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 루프 :
(*) for (char ch: first + last)
gdb로 프로그램을 실행했을 때 예상대로 여기에서 중단 점이 트리거되었습니다. 그러나 실행을 계속하면 중단 점이 다시 트리거되지 않고 프로그램이 완료 될 때까지 실행됩니다.
이 동작을 시스템에서 일관되게 재현 할 수 있습니다. 루프 본문에 브레이크 포인트를 설정하고 적중 될 때까지 실행하면 루프의 맨 위에 중단 점을 추가하고 "계속"을 누르면 디버거가 루프 중단 점을 건너 뜁니다.
범위 기반 for 루프가 일련의 다른 초기화 단계로 확장되어 (디버그 창에서 생성 된 임시 변수가 실제로 표시됨) 브레이크 포인트가 루프 단계가 아닌 초기화 단계. 그렇다면 이해할 만하지만 놀랍도록 반 직관적입니다.
이 문제에 대한 현재 해결 방법은 루프의 맨 위에 루프 안의 첫 번째 문에 중단 점을 설정하는 것이지만 직관적이지 못하며 교육적 관점에서 볼 때 앞으로의 잘못된 조언입니다.
- 내 분석이 정확 :
내 질문은 다음과 같습니다?
- 내 gdb 버전과 관련이 있습니까? 내가 할 수있는 GDB를 얻기 위해 5.4.0 20160609.
- 이 방법을
- 우분투 16.04 및
- g ++ (5.4.0-6ubuntu1 ~ 16.04.4 우분투)가되어 사용하고 있습니다 범위 기반 for 루프의 중단 점을 초기화 단계가 아닌 루프 본문의 중단 점으로 처리합니까?
"이 OS 또는 Qt Creator는 버전에 맞습니까?" 그것은 GDB의 변종 일 수 있습니다. Visual C++ 및/또는 Clang으로이 작업을 시도해보고 동일한 결과를 얻었는지 확인하십시오. 결국 Qt Creator의 디버거는 단지 그래픽 프론트 엔드에 불과합니다. – MrEricSir
@MrEricSir 전화하세요! 이것은 GDB 문제입니다. 나는 몇몇 구글 검색으로 이것에 관해 무엇인가를 발견 할 수 없다. 그래서 나는 그것을 다시 집중하도록 질문을 업데이트했다. – templatetypedef
프로덕션 디버깅을 위해 어셈블러 뷰로 전환 한 다음 코드의 반복 부분에 중단 점을 설정할 수 있습니다. 그러나 나는 "어셈블러 뷰로 전환"이 아마 가르쳐야 할 * * * 일이 아니라고 생각합니다! –