현재 일부 코드를 디버깅하고 있는데 다음 줄을 보았습니다.
for (std::size_t j = M; j <= M; --j)
(휴가중인 사장님이 작성했습니다.)
정말 이상해 보입니다.
그것은 무엇을합니까? 나에게는 무한 루프처럼 보입니다.
답변
std::size_t
C ++ 표준에 의해 unsigned
유형 이 보장됩니다 . 그리고 unsigned
유형을 0에서 감소 시키면 표준은 그 결과가 해당 유형에 대해 가장 큰 값임을 보장합니다.
그 래핑 된 값은 항상 M
1 보다 크거나 같으 므로 루프가 종료됩니다.
따라서 유형에 j <= M
적용될 때 unsigned
“루프를 0으로 실행 한 다음 중지”라고 말하는 편리한 방법입니다.
j
원하는 것보다 더 크게 실행 하거나 슬라이드 연산자를 사용하는 것과 같은 대안이 for (std::size_t j = M + 1; j --> 0; ){
존재합니다. 더 많은 입력이 필요하지만 분명히 더 명확합니다. 그러나 한 가지 단점은 (첫 번째 검사에서 생성되는 당황스러운 효과를 제외하고) Java와 같이 서명되지 않은 유형이없는 언어로 잘 이식되지 않는다는 것입니다.
또한 상사가 선택한 계획은 unsigned
세트 에서 가능한 값을 “차용” 합니다.이 경우에 M
설정된 경우 std::numeric_limits<std::size_t>::max()
올바른 동작을 갖지 않습니다. 사실,이 경우 루프는 무한 합니다. (그것이 당신이 관찰하고있는 것입니까?) 코드에 그 효과에 대한 주석을 삽입해야하고, 심지어 그 특정 조건에 대해 주장해야합니다.
(1) 에 따라 M
되지 않는 std::numeric_limits<std::size_t>::max()
.
답변
상사가 하려고 했던 것은 M
0부터 0까지 카운트 다운 하여 각 숫자에 대해 몇 가지 작업을 수행하는 것이 었습니다 .
불행히도 그것이 실제로 무한 루프를 제공 할 수있는 M
최대 size_t
값 인 경우 가 있습니다. 그리고 서명되지 않은 값이 0에서 감소 할 때 무엇을할지는 잘 정의되어 있지만, 저는 코드 자체가 엉성한 사고의 예라고 주장합니다. 특히 상사 시도의 결점없이 완벽하게 실행 가능한 솔루션이 있기 때문입니다.
더 안전한 변형 (내 의견으로는 여전히 엄격한 범위 제한을 유지하면서 더 읽기 쉬움)은 다음과 같습니다.
{
std::size_t j = M;
do {
doSomethingWith(j);
} while (j-- != 0);
}
예를 들어 다음 코드를 참조하십시오.
#include <iostream>
#include <cstdint>
#include <climits>
int main (void) {
uint32_t quant = 0;
unsigned short us = USHRT_MAX;
std::cout << "Starting at " << us;
do {
quant++;
} while (us-- != 0);
std::cout << ", we would loop " << quant << " times.\n";
return 0;
}
이것은 기본적으로와 동일한 작업을 수행 unsigned short
하며 모든 단일 값을 처리하는 것을 볼 수 있습니다 .
Starting at 65535, we would loop 65536 times.
do..while
위 코드 의 루프를 상사가 기본적으로 수행 한 작업으로 대체하면 무한 루프가 발생합니다. 그것을 시도하고보십시오 :
for (unsigned int us2 = us; us2 <= us; --us2) {
quant++;
}