예기치 않은 무한 루프 출력: C 컴파일의 문제
C에서는 겉보기에 무해해 보이는 특정 작업이 다음과 같이 예상치 못한 동작으로 이어질 수 있습니다. 다음 코드 조각:
<code class="cpp">#include <iostream> #include <complex> using namespace std; int main() { complex<int> delta; complex<int> mc[4] = {0}; for (int di = 0; di < 4; di++, delta = mc[di]) { cout << di << endl; } return 0; }</code>
예상되는 "0, 1, 2, 3" 출력과 달리 코드는 실수로 끝없는 일련의 숫자를 생성합니다. 이 당혹스러운 동작은 정의되지 않은 동작과 관련된 미묘하지만 중요한 문제에서 비롯됩니다.
정의되지 않은 동작 수수께끼
할당문 delta = mc[di]는 mc 배열에 액세스합니다. 루프의 마지막 반복에서 유효한 인덱스를 초과합니다. C 영역에서 범위를 벗어난 메모리에 액세스하는 것은 정의되지 않은 동작, 예측할 수 없는 결과가 지배하는 영역을 구성합니다.
공격적인 루프 최적화: 양날의 검
컴파일러는 성능을 향상시키기 위해 공격적인 루프 최적화를 사용하는 경우가 많습니다. 이러한 최적화는 정의되지 않은 동작이 없다는 가정을 활용합니다. 주어진 코드의 경우, 컴파일러는 di < 4는 정의되지 않은 동작이 발생하지 않는다는 가정에 따라 실제 배열 범위에 관계없이 항상 true를 유지합니다. 결과적으로 이 가정은 경계 검사를 제거하여 루프가 무한정 반복되도록 합니다.
Unraveling the Mystery
최적화가 활성화되고 -fno-aggressive가 없는 GCC -loop-optimizations 플래그는 무한 루프 동작을 나타냅니다. 그러나 해당 플래그를 활성화하면 잘못된 동작이 사라집니다. 어셈블리 코드를 검사하면 di < 4 체크가 삭제되고 무조건 점프로 대체되었습니다.
함정 피하기
이러한 함정을 방지하려면 정의되지 않은 동작을 방지하고 명시적으로 확인하는 것이 중요합니다. 배열 경계. 또한 경고 플래그를 통해 적절한 진단 메시지를 보장하면 잠재적인 문제에 대한 귀중한 통찰력을 얻을 수 있습니다.
결론
정의되지 않은 동작은 C 코드에서 예상치 못한 예측할 수 없는 동작으로 이어질 수 있습니다. 예상치 못한 결과를 방지하려면 이러한 잠재적 위험을 인식하고 건전한 프로그래밍 방식을 부지런히 준수하는 것이 중요합니다.
위 내용은 이 C 코드가 단순한 출력 대신 무한 루프를 발생시키는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!