컴파일러 최적화 및 정의되지 않은 동작: C가 Bool에 대한 특정 가정을 허용합니까?
소개
이 기사에서는 C 표준이 컴파일러가 특정 숫자를 가정하도록 허용하는지 여부를 조사합니다. bool에 대한 표현과 그러한 가정이 프로그램 충돌과 같은 결과로 이어질 수 있는지 여부.
문제
프로그래머가 초기화되지 않은 bool 값을 사용하는 동안 프로그램 충돌이 발생했습니다. bool을 문자열로 직렬화하는 함수입니다. 놀랍게도 최적화가 활성화된 특정 컴파일러를 사용하는 특정 플랫폼에서만 충돌이 발생했습니다.
문제 코드:
1 2 3 4 5 |
|
Clang 5.0.0 및 최적화로 코드를 실행할 때( -O2), 충돌이 발생할 수 있습니다. 이 동작은 문자열 "true"와 "false"의 길이가 1만큼만 다르다는 최적화 프로그램의 추론으로 인해 발생합니다. 실제 길이를 계산하는 대신 boolValue 값을 0 또는 1이라고 가정하여 사용합니다.
1 2 |
|
질문: 표준 고려 사항
이 기사는 질문: C 표준에서는 컴파일러가 bool이 '0' 또는 '1'의 내부 숫자 표현만 가질 수 있다고 가정하고 이를 그런 방식으로 사용할 수 있도록 허용합니까? 아니면 구현에서 모든 bool이 0 또는 1만 포함한다고 가정하고 다른 값은 정의되지 않은 동작 영역이라고 가정하는 구현 정의 동작의 경우입니까?
답변: 표준 적합성
저자에 따르면 ISO C에서는 이를 구현하는 것이 허용되지만 필수는 아닙니다. 선택. ISO C에서는 bool의 내부 표현이 무엇인지 지정하지 않으므로 구현이 자체적으로 가정할 수 있습니다.
컴파일러 최적화 동작
System V ABI: x86-64에서 일반적으로 사용되는 System V ABI를 사용하는 플랫폼의 경우 시스템에서 함수에 전달된 bool 인수는 레지스터의 하위 8비트에서 0 = false 및 1 = true 비트 패턴으로 표시됩니다. 메모리에서 bool은 0 또는 1의 정수 값을 가져야 하는 1바이트 유형입니다.
이 ABI 결정을 통해 컴파일러는 bool에 대해 0 또는 1을 가정하고 비트 단위로 수행하는 등의 최적화를 활용할 수 있습니다. 비용이 많이 드는 유형 변환 대신 작업. 제공된 예에서 최적화 프로그램은 이 동작을 활용하여 strlen(whichString)을 5U - boolValue로 최적화했습니다.
기타 구현 및 가정:
System V ABI가 널리 사용되지만 다른 구현에서는 다른 가정을 할 수 있습니다. 예를 들어 0 = false이고 0이 아닌 값 = true를 고려할 수 있습니다. 이러한 시나리오에서 컴파일러는 초기화되지 않은 bool 값에 대해 충돌하는 코드를 생성하지 않을 수 있지만 여전히 정의되지 않은 동작으로 간주될 수 있습니다.
프로그램 충돌의 위험
C 표준은 이러한 최적화를 허용하지만 정의되지 않은 동작이 발생하는 프로그램은 전체 존재에 대해 완전히 정의되지 않은 것으로 간주된다는 점에 유의하는 것이 중요합니다. 이는 실제로 호출되지 않은 함수에서 정의되지 않은 동작이 발생하더라도 충돌이 발생할 수 있음을 의미합니다.
모범 사례 및 정의되지 않은 동작 방지
컴파일러가 점점 더 발전하고 있습니다. 구현에 대한 내부 이해를 바탕으로 동작을 가정하여 코드 최적화에 점점 더 적극적으로 참여하고 있습니다. 프로그래머는 구현 가정에 의존하지 않고 자신의 코드가 이식 가능한 어셈블리 언어처럼 작동할 것이라는 가정 없이 유효한 C인지 확인하는 것이 중요합니다.
문제를 방지하려면 프로그래머는 다음 모범 사례를 따라야 합니다.
위 내용은 C 컴파일러는 부울의 숫자 표현이 0 또는 1이라고 가정할 수 있으며 이로 인해 정의되지 않은 동작이 발생합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!