2014-11-06 6 views
5

는, 나는 다음과 같은 코드 조각 한 : 나는 코드를 컴파일 할 때 어떤 이유에서IAR 컴파일러가 멈추는 이유는 무엇입니까? <strong>IAR EWARM</strong> 개발 도구 (v7.10.3)를 사용하여 내 임베디드 프로젝트에서

/* 1 */ uint32_t packet_sync = 0; 
/* 2 */ uint32_t synced  = 0; 
/* 3 */ uint32_t gpio  = 0; 

/* 4 */ while (1) { 
/* 5 */  if ((packet_sync != 0) && ((packet_sync = gpio) == 0)) { 
/* 6 */  if (synced < 2) { 
/* 7 */   synced++; 
/* 8 */  } 
/* 9 */  } 
/* 10 */ }; 

는, 컴파일러는에 걸리면 편집의 중간. 나는 여러 가지 구조로 놀아 보았는데, 내가 만든 사소한 변화처럼 보이고, 문제를 제거한다. (그러나 코드를 잘못 만들 수도있다.) 예를 들어, #의 6A에서 NOP를 추가하고 코드 컴파일을 성공적으로 수행합니다

/* 6 */  if (synced < 2) { 
/* 6a */   __NOP(); 
/* 7 */   synced++; 
/* 8 */  } 
성공적인 변화의

다른 예는 라인 # 7을 제거하거나 같은 라인 # 5를 변경 :

/* 5 */  if ((packet_sync != 0) && ((gpio) == 0)) { 

몇 가지 변형이 있습니다.

문제가있는 코드에서 C 규칙 위반이 표시되지 않으며 Visual Studio 2013에서 올바르게 컴파일됩니다. 놓친 것이 있습니까? 이 코드가 컴파일되지 않는 이유는 무엇입니까?

* 참고 : 제시된 코드는 실제 코드를 추출한 것이며 논리적으로 의미가 없습니다.


업데이트 : 코드는 "높은"/ "균형 잡힌"최적화 레벨로 컴파일됩니다. 최적화 수준이 낮아지면 컴파일이 정상적으로 끝납니다.

"높음"레벨을 사용하지만 "사용 가능한 변환 :"상자에서 최적화 옵션을 제거하면 멈추게됩니다. 또한 '속도'및 '크기'옵션을 선택해야합니다.

+0

어떤 컴파일러 옵션을 사용하고 있습니까? 예를 들어 최적화를 켜거나 끄거나 C++ 컴파일 대신 C?를 사용하면 결과가 변경됩니까? 문제가 무엇인지 모르기 때문에 문제를 재현 할 수있는 충분한 정보가 "추상적"이라고 제시하면 어떻게 확신 할 수 있습니까? 당신이 주장하는 코드는 확실히 "SSCCE"가 아닙니다! – Clifford

+0

첫 번째 조각에서'gpio'는 루프 불변입니다. 다른 문맥에서 변경 될 수 있다면 '휘발성 (volatile)'이라고 선언해야합니다. 다른 변수는 코드의 다른 곳에 사용법에 따라 '휘발성'으로 선언해야 할 수도 있습니다. – Clifford

+0

@ Clifford - SSCCE를 주장하지 않았습니다. Compileable에 대한 하나의 "C"가 제거되었습니다.이 코드는 적절한 함수로 래핑되어야하기 때문입니다. 'gpio'는 실제로 불변합니다 (추출 코드에서). 이 코드는 프로젝트에서 정의 된대로 표시되었습니다. 변수는 변동이 없습니다. 당신은 코드가 * 크기 * 최적화되었다는 것을 언급하지 않았다는 점에서 옳다. 불행하게도, 프로젝트에서 거대한 재 작업을하지 않고 최적화를 제거하는 것은 어렵습니다. – ysap

답변

2

컴파일러가 글자 그대로 "멈추다"면, 즉 프로세스가 종료되도록 컴파일러가 종료되면 컴파일러 버그가 발생합니다.

특정 입력에 대해 중단하지 않은 코드 조각 (= 컴파일러)이 왜 그렇게 어려운지 알아내는 것이 좋습니다.

반면에 컴파일러가 코드에 오류를보고하기 때문에 컴파일러가 멈춘다는 것을 알면 물론 그 사실을 알면 유용 할 것입니다.

+0

프로세스가 멈추었습니다. 중지하려면 "빌드 중지"버튼을 클릭해야합니다. 오류보고는 제공되지 않습니다. – ysap

+1

물론 매우 어렵습니다 ... 그렇지 않으면 여기에 질문을 게시하지 않겠습니다 ;-) – ysap

+0

@ysap 저는 가볍게 아이러니했습니다. 나는 당신이 요구하는 것이 근본적으로 원격으로 파악하는 것이 불가능하다고 주장 할 것이다. 컴파일러에 대한 상용 지원이 있습니까? – unwind

2

나는 이것이 컴파일러 버그라고 생각합니다. 컴파일러 벤더에게 버그를 제출하고 컴파일러 버그를 재현 할 수 있도록 결함있는 소스 코드를 첨부하십시오. 행운을 빌어. 지금이 버그를 해결하십시오.

+0

감사합니다. 기본적으로 정확하지만, @ unwind에 대한 제 의견을 참조하십시오. – ysap

+1

버그를 보여주는 MCVE를 제작자가 잘 보여줄 수 있도록 제작합니다. 재현 할 수 없으면 수정하거나 시간을 낭비하지 않습니다. –

2

최적화는 모든 컴파일러의 가장 복잡한 부분이므로 컴파일러 버그의 가장 큰 부분입니다. 특히 개발 팀이 작은 "좁은 시장"컴파일러와 데스크톱 시스템 컴파일러 인 경우 사용자 수가 적습니다.

최적화 적용에는주의해야 할 두 가지 결과가 있습니다. 컴파일러 자체는 버그가있을 수 있으며 (이 경우에는 가능성이 있음) 사용자 코드의 "정의되지 않은 동작"의 모든 영역이 최적화 상태에서 동작을 바꿀 수 있습니다. 최적화를 사용해야하는 경우 광범위하게 테스트 할 준비가 필요합니다. 생성 된 코드가 디버그/개발 빌드와 반드시 동일 할 필요는 없습니다.

이 경우 문제를 공급 업체에보고해야합니다. 실제로 컴파일 할 수있는 예제와 프로젝트 구성이 이상적입니다.즉각적인 문제를 해결하려면 volatile 키워드를 현명하게 사용하면 문제가 해결 될 수 있습니다. 옵티마이 저는 다른 방법으로 영향을 미치지 않는 변수를 제거하기 위해 열심히 노력할 것입니다. 옵티 마이저가 동일한 경로를 사용하는 것을 피할 수 있으면 버그를 피할 수 있습니다. volatile을 올바로 사용하지 않으면 어떤 경우에도 최적화하에 your code may well exhibit bugs을 사용하십시오. 예를 들어, 일부 변수는 분명히 휘발성으로 선언해야하지만 예제는 "실제"가 아니지만 "설명 적이기"때문에 조언 할 수 없습니다.

대안으로이 코드 섹션이나 소스 파일에 대해 선택적으로 최적화를 비활성화 할 수도 있습니다. 코드가 전혀 작동하지 않도록 최적화가 필요합니까? 그렇지 않으면 최적화를 사용하지 않으면 디버그와 릴리스 된 코드 간의 동작이 변경되지 않으므로 첫 번째 인스턴스에서 디버깅이 간단 해집니다. 코드 크기 나 성능 관련 문제를 해결할 때 최적화를 사용하는 것이 좋을 것입니다.

+0

감사합니다. 이것은 모두 사실이며 잘 알려진 사실입니다. 실제 코드에서는'gpio'가 적절히 선언됩니다. 더구나, 나는 나중에이를 단순한 '0'으로 바꾸었고, 문제가 지속되어 표현의 변동성이 그것의 근원이 아니다. 내가이 질문에서 지적했듯이,'if' 내부에'NOP' 명령어를 추가하는 것만으로이 문제를 해결하는 것은 쉽습니다. 최적화와 관련된 포인트는 유효하지만,이 경우 코드는 이미 CPU의 메모리를 오버 플로우시켜 중요한 경로가되므로 크기를 줄이는 것은 물론 속도를 높이는 것이 중요합니다. 어쨌든, 어제 버그 리포트가 보냈습니다. – ysap

+0

@ysap : 우리는 이것을 포기해야한다고 생각합니다. 우리는 대표적이지 않은 코드 단편에 대해 논의하고 있으며 동일한 도구를 사용하는 다른 사람이 문제를 재현 할 수 없도록합니다. 또한 그것은 도구 나 프로그램 그 자체에 관한 것으로 보입니다. 아마 여기에서 마이그레이션해서는 안됩니다. – Clifford