컴파일러는 어떻게 그렇게 신뢰할 수 있습니까?


62

우리는 정확성이 주어진 것처럼 매일 컴파일러를 사용하지만 컴파일러도 프로그램이며 잠재적으로 버그를 포함 할 수 있습니다. 나는 항상이 완벽한 견고성에 대해 궁금했다. 컴파일러 자체에 버그가 발생한 적이 있습니까? 이것이 무엇이며 컴파일러 자체에 문제가 있다는 것을 어떻게 알았습니까?

... 어떻게 합니까 그들은 컴파일러 그렇게 신뢰성을?


16
글쎄, 그들은 컴파일러를 컴파일합니다 ...
Michael K

31
그들은 완전하지 않습니다. 컴파일러 버그가 있습니다. 매우 드물기 때문입니다.
ChrisF

5
코드 스택을 내릴수록 버그가 더 희박 해집니다. 응용 프로그램 버그는 컴파일러 버그보다 일반적입니다. 컴파일러 버그는 CPU (마이크로 코드) 버그보다 일반적입니다. 이것은 실제로 좋은 소식입니다. 다른 방향인지 상상할 수 있습니까?
Fixee 2012

당신은 컴파일러 방법을 관찰하여 뭔가를 배울 수 않는 많은 버그가 (SDCC과 같습니다!) 훨씬 더 강력하고 신뢰할 수 GCC 같은 컴파일러는 다르다.
벤 잭슨

답변:


96

시간이 지남에 따라 수천 명 또는 수백만 명의 개발자가 사용량을 통해 철저히 테스트합니다.

또한 해결해야 할 문제는 매우 상세한 기술 사양에 의해 잘 정의되어 있습니다. 또한 작업의 특성상 단위 / 시스템 테스트에 쉽게 적합합니다. 즉, 기본적으로 텍스트 입력을 매우 특정한 형식으로 변환하여 다른 종류의 잘 정의 된 형식 (일부 바이트 코드 또는 기계 코드)으로 출력합니다. 따라서 테스트 사례를 쉽게 만들고 확인할 수 있습니다.

또한, 버그는 재현하기도 쉽습니다. 정확한 플랫폼 및 컴파일러 버전 정보와는 별도로 입력 코드 만 있으면됩니다. 컴파일러 사용자 (개발자 자신)는 일반적인 컴퓨터 사용자보다 훨씬 더 정확하고 자세한 버그 보고서를 제공하는 경향이 있습니다 :-)


32
또한 많은 컴파일러 코드가 올바른 것으로 입증 될 수 있습니다.
biziclop

@biziclop, 좋은 지적, 이것은 작업의 특별한 본성의 또 다른 결과입니다.
Péter Török

최초의 완전한 컴파일러는 John Backus가 FORTRAN 언어를 위해 1957 년에 작성했습니다. 컴파일러 기술은 50 년이 넘었습니다. 우리는 다른 사람들이 지적했듯이 컴파일러에 버그가 있음에도 불구하고 올바른 시간을 가졌습니다.
leed25d

@biziclop, 실제로, 어휘 분석기 및 파서와 같은 일부 구성 요소는 문법에서 자동 생성 될 수 있으며, 이는 버그의 위험을 다시 낮 춥니 다 (렉서 / 파서 생성기가 강력 할 경우 일반적으로 위에 열거 된 것과 같은 이유로) .
Péter Török

2
@Peter : Lexer / 파서 생성기는보다 널리 사용되는 컴파일러에서 다소 드문 것 같습니다. 대부분 해당 언어에 대해 속도가 충분하고 스마트 한 파서 / 렉서 생성기 부족 등 여러 가지 이유로 렉서 및 파서를 작성합니다 (예 : C ).

61

지금까지의 모든 위대한 답변 외에도

"관찰자 편견"이 있습니다. 버그는 관찰되지 않으므로 버그가 없다고 가정합니다.

당신처럼 생각 했었어 그런 다음 전문적으로 컴파일러를 작성하기 시작했으며 거기에 많은 버그가 있습니다.

사람들이 작성하는 나머지 모든 코드의 99.999 %와 유사한 코드를 작성하기 때문에 버그가 표시되지 않습니다. 메서드를 호출하고 루프를 실행하고 정상적인 비즈니스 문제를 해결하는 일반 개발자이기 때문에 환상적이고 이상한 작업을 수행하지 않는 완전히 정상적이고 간단하며 명확하게 올바른 코드를 작성할 수 있습니다.

컴파일러 버그는 분석하기 쉬운 일반 코드 시나리오가 아니기 때문에 컴파일러 버그가 표시되지 않습니다. 버그는 작성하지 않은 이상한 코드 분석에 있습니다.

반면에 나는 반대 관찰자 편견이 있습니다. 매일 매일 미친 코드가 보이므로 컴파일러는 버그로 가득 찬 것 같습니다.

모든 언어의 언어 사양에 동의하고 해당 언어에 대한 컴파일러 구현을 사용하여 모호한 경우에 집중하여 컴파일러가 정확하게 사양을 구현했는지 여부를 결정하려고 열심히 노력했다면 곧 발견 될 것입니다. 컴파일러 버그가 자주 발생합니다. 예를 들어 보겠습니다. 문자 그대로 5 분 전에 찾은 C # 컴파일러 버그가 있습니다.

static void N(ref int x){}
...
N(ref 123);

컴파일러는 세 가지 오류를 제공합니다.

  • ref 또는 out 인수는 지정 가능한 변수 여야합니다.
  • N (ref int x)에 가장 잘 맞는 인수에 잘못된 인수가 있습니다.
  • 인수 1에 "ref"가 없습니다.

분명히 첫 번째 오류 메시지는 정확하고 세 번째 오류 메시지는 버그입니다. 오류 생성 알고리즘은 첫 번째 인수가 왜 유효하지 않은지 알아 내려고합니다.이를보고, 상수인지, 소스 코드로 돌아가서 "ref"로 표시되어 있는지 확인하지 않습니다. 오히려 상수를 참조로 표시하기에 어리석은 사람은 없다고 가정하고 참조가 누락되어야한다고 결정합니다.

올바른 세 번째 오류 메시지가 무엇인지는 확실하지 않지만 그렇지 않습니다. 실제로 두 번째 오류 메시지가 올바른지 확실하지 않습니다 . 과부하 해결에 실패하거나 "ref 123"을 올바른 유형의 ref 인수로 취급해야합니까? 이제 올바른 행동이 무엇인지 판단 할 수 있도록 몇 가지 생각을하고 심사 팀과상의해야합니다.

123을 ref로 전달하려고 시도하는 것처럼 어리석은 짓을하지 않기 때문에이 버그를 본 적이 없습니다. 그리고 만약 그렇다면, 첫 번째 오류 메시지가 정확하고 문제를 진단하기에 충분하기 때문에 세 번째 오류 메시지가 의미가 없다는 것을 알지 못할 것입니다. 그러나 컴파일러를 깨 려고 하기 때문에 그런 일을 하려고 합니다. 당신이 시도하면 버그도 볼 수 있습니다.


4
첫 번째 오류 메시지 후에 좋은 오류 메시지는 수행하기가 매우 어렵습니다.

더 나은 :) 완전히 "바보"- 증거 컴파일러를 제작 한 후 소비 에너지가 있어야합니다 Sureöy
Homde

2
@MKO : 물론입니다. 많은 버그가 수정되지 않습니다. 때로는 수정이 너무 비싸고 시나리오가 너무 모호하여 비용이 이점으로 정당화되지 않습니다. 그리고 때때로 충분한 사람들이 당신이 그것을 유지해야하는 "버기"행동에 의존하게되었습니다.
Eric Lippert

mmm ... 오류 메시지로 끝나는 버그는 "괜찮습니다". 코드를 조금씩 조작하여 작동시킬 수 있습니다. 컴파일러 가 소스 코드를 수락 하고 "잘못된"어셈블러 출력을 생성 하는 버그는 어떻습니까? 무섭다
지안루카 제 티니

7
@aij : "확실히 합법적 인 C # 코드"의 의미에서 수정하십시오. 예를 들어, 하나의 인터페이스에는 속성이 있고 다른 하나는 속성과 동일한 이름의 메소드를 갖는 두 개의 인터페이스를 상속하는 인터페이스를 포함하는 프로그램을 작성한 적이 있습니까? 사양을 보지 않고 빨리 : 그것은 합법적 입니까? 이제 해당 메소드를 호출했다고 가정하십시오. 모호 합니까? 등등. 사람들은 항상 자신이 의미하는 바를 수행하지 않는 코드를 작성합니다. 그러나 법적 C #인지 여부를 말하기 위해 사양 전문가가되어야하는 코드를 작성하는 경우는 거의 없습니다.
Eric Lippert

51

농담 해? 컴파일러에도 버그가 있으며 실제로로드됩니다.

GCC는 아마도 지구상에서 가장 유명한 오픈 소스 컴파일러이며 버그 데이터베이스를 살펴보십시오. http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=-- -

GCC 3.2와 GCC 3.2.3 사이에서 수정 된 버그 수를 살펴보십시오. http://gcc.gnu.org/gcc-3.2/changes.html

Visual C ++와 같은 다른 사람들은 시작조차 원하지 않습니다.

컴파일러를 어떻게 안정적으로 만들 수 있습니까? 처음에는 부하와 단위 테스트가 있습니다. 그리고 지구 전체가 테스터를 어지럽히 지 않도록 사용합니다.

진지하게, 내가 믿는 컴파일러 개발자는 뛰어난 프로그래머이며, 완벽하지는 않지만, 상당히 펀치감이 듭니다.


19

나는 하루에 두세 번 만났다. 하나를 감지하는 유일한 방법은 어셈블리 코드를 보는 것입니다.

다른 포스터가 지적한 이유로 컴파일러는 신뢰성이 높지만 컴파일러 신뢰성은 종종 자체 이행 평가라고 생각합니다. 프로그래머는 컴파일러를 표준으로 간주하는 경향이 있습니다. 문제가 발생하면 결함이 있다고 가정하고 (현재 시간의 99.999 % 때문) 코드를 변경하여 컴파일러 문제를 해결하십시오. 예를 들어, 높은 최적화 설정에서 충돌하는 코드는 분명히 컴파일러 버그이지만 대부분의 사람들은 버그를 조금만 설정하고 버그를보고하지 않고 계속 진행합니다.


6
"컴파일러를 표준으로 보는 경우"+1 언어를 정의하는 것은 컴파일러와 표준 라이브러리라는 두 가지가 오랫동안 유지되어 왔습니다. 표준 문서는 문서 일뿐입니다.
메이슨 휠러

8
@Mason : 하나의 구현으로 언어에 적합합니다. 언어가 많은 언어의 경우 표준이 필수적입니다. 실제 영향은, 만약 당신이 무언가에 대해 불평한다면, 벤더가 표준 문제라면 당신을 진지하게 받아들이고, 그것이 정의되지 않은 행동이나 그와 비슷한 것이라면 당신을 털어 놓을 것입니다.
David Thornley

2
@Mason-그것은 표준에 맞는 표준을 가진 언어가 거의 없기 때문입니다. btw, IMHO는 좋은 일이 아닙니다. 진지한 발전에는 하나 이상의 OS 세대가 지속될 것으로 예상됩니다.
Rook

1
@David :보다 정확하게는 하나의 지배적 인 구현입니다. Borland는 Pascal을 정의하고 Microsoft는 ANSI 및 ECMA의 의견에 관계없이 C #을 정의합니다.
dan04

4
높은 최적화에서 C, C ++ 또는 Fortran 코드 충돌은 컴파일러 버그보다 잘못된 입력 코드입니다. 나는 종종 매우 새로운 하드웨어를 위해 최신 및 시험판 컴파일러와 함께 작업하며 최적화 관련 오류를 꽤 정기적으로 봅니다. 이러한 언어는 정의되지 않은 동작에 대한 개념을 가지고 있으며 부적합 프로그램의 처리를 지정하지 않기 때문에 결국 어셈블리에 대해 충돌을 매우 신중하게 확인해야합니다. 80-90 %의 경우 응용 프로그램 코드가 잘못되었으며 컴파일러가 아닙니다.
Phil Miller

14

컴파일러에는 정확성으로 이어지는 몇 가지 속성이 있습니다.

  • 도메인은 매우 잘 알려져 있으며 연구되었습니다. 문제가 잘 정의되어 있으며 제공된 솔루션이 잘 정의되어 있습니다.
  • 자동 테스트는 컴파일러가 올바르게 작동하는지 증명하기에 충분합니다.
  • 컴파일러는 대부분의 다른 프로그램보다 더 많은 오류 공간을 처리하기 위해 시간이 지남에 따라 누적되는 매우 광범위하고 일반적으로 공개, 자동화 및 단위 테스트를 수행합니다.
  • 컴파일러는 많은 수의 안구가 결과를보고 있습니다

2
또한 많은 경우 코드가 오래되고 GCC는 20 년이 넘었으며 다른 많은 것들과 마찬가지로 많은 버그가 오랜 기간 동안 해결되었습니다.
Zachary K

13

우리는 매일 컴파일러를 사용합니다

... 그리고 컴파일러를 어떻게 그렇게 안정적으로 만들 수 있습니까?

그들은하지 않습니다. 우리는하다. 모두가 항상 그것들을 사용 하기 때문에 버그가 빨리 발견됩니다.

숫자 게임입니다. 컴파일러는 광범위하게 사용되기 때문에 누군가 버그 발생할 가능성이 높지만 사용자가 너무 많기 때문에 누군가가 당신을 구체적으로 대변 할 가능성 은 거의 없습니다 .

따라서 사용자의 관점에 따라 다릅니다. 모든 사용자에게 컴파일러는 버그가 있습니다. 그러나 당신이 한 전에 경우에, 그래서 다른 사람의 코드와 비슷한 조각을 컴파일 할 가능성이 높다 이었다 버그, 그것은 당신을을하지 포함했는지 것이다 당신의에서, 그래서 각각의 버그처럼 보이는, 관점 절대 거기.

물론 그 외에도 여기에 다른 모든 대답을 추가 할 수 있습니다. 컴파일러는 잘 연구되고 잘 이해되어 있습니다. 쓰기가 어렵다는 신화가 있습니다. 이는 매우 똑똑하고 훌륭한 프로그래머 만이 실제로 작성하려고 시도 할 때주의를 기울입니다. 일반적으로 테스트하기 쉽고 스트레스 테스트 또는 퍼지 테스트가 쉽습니다. 컴파일러 사용자는 전문 프로그래머 인 경향이 있으므로 고품질 버그 보고서가 생성됩니다. 그리고 다른 방법 : 컴파일러 작성자는 자신의 컴파일러 사용자 인 경향이 있습니다.


11

이미 모든 답변 외에도 다음을 추가하고 싶습니다.

나는 많은 시간, 공급 업체가 자신의 개밥을 먹고 있다고 생각 합니다. 즉, 그들은 스스로 컴파일러를 작성하고 있습니다.


7

나는 종종 컴파일러 버그에 부딪쳤다.

테스터가 적은 어두운 구석에서 찾을 수 있습니다. 예를 들어 GCC에서 버그를 찾으려면 다음을 시도하십시오.

  • 크로스 컴파일러를 빌드하십시오. GCC의 구성 및 빌드 스크립트에서 문자 그대로 수십 가지 버그를 발견 할 수 있습니다. 일부는 GCC 컴파일 중 빌드 실패를 일으키고 다른 일부는 크로스 컴파일러가 작업 실행 파일을 빌드하지 못하게합니다.
  • profile-bootstrap을 사용하여 Itanium 버전의 GCC를 빌드하십시오. 마지막으로 GCC 4.4 및 4.5 에서이 작업을 시도했지만 작동하는 C ++ 예외 처리기가 생성되지 않았습니다. 최적화되지 않은 빌드는 정상적으로 작동했습니다. 아무도 내가보고 한 버그를 수정하는 데 관심이없는 것처럼 보였고 GCC asm 메모리 사양에서 훼손 된 것을 파헤 치려고 시도한 후에 직접 수정을 포기했습니다.
  • 배포판 빌드 스크립트를 따르지 않고 최신 작업으로 자신의 작업 GCJ를 빌드하십시오. 감히

우리는 IA64 (Itanium)에 많은 문제를 발견했습니다. 해당 플랫폼에 대한 고객이 많지 않으므로 일반적인 버그 수정은 최적화 수준을 줄이는 것입니다. 이것은 다른 답변으로 되돌아갑니다. 인기있는 아키텍처를위한 인기있는 언어의 컴파일러는 일반적으로 충분한 사용자 노출과 꽤 좋은 지원을 받았지만 덜 인기있는 아키텍처 및 / 또는 언어로 갈수록 신뢰성이 떨어질 것으로 예상합니다.
Omega Centauri

@ 오메가 : 최적화를 줄이는 것은 모든 사람들이하는 것처럼 보입니다. 안타깝게도 Itanium 성능 우수한 컴파일러를 필요로합니다. 잘 ...
Zan Lynx

들었어요 솔직히 AMD는 x86-64를 사용하여 인텔에 손을 댔습니다 (많은 사마귀에도 불구하고 그렇게 나쁘지는 않습니다). 소스 파일을 분리 할 수 ​​있으면 문제가있는 것이므로 격리 할 수 ​​있고 해결 방법을 찾을 수 있습니다. 그것이 중요한 플랫폼이라면 IA64에게는 그렇지 않습니다.
오메가 센타 우리

@Omega : 불행히도, 나는 Itanium을 정말로 좋아합니다. 훌륭한 건축입니다. 나는 x86과 x86-64를 쓸모없는 것으로 간주하지만 물론 결코 죽지 않을 것입니다.
Zan Lynx

x86은 약간 이상합니다. 그들은 그것에 새로운 것을 계속 추가하므로 한 번에 하나의 사마귀가 자랍니다. 그러나 비 순차적 실행 엔진은 꽤 잘 작동하며 새로운 SSE => AVX 항목은 코딩하려는 사람들에게 실제 기능을 제공합니다. 틀림없이 반 쓸모없는 일을하는 데 전념하는 많은 트랜지스터가 있지만, 이는 레거시 호환성에 대한 대가입니다.
Omega Centauri

5

몇 가지 이유:

  • 컴파일러 작가는 " 자신의 개밥을 먹는다 ".
  • 컴파일러는 잘 이해 된 CS 원칙 을 기반으로 합니다 .
  • 컴파일러는 매우 명확한 사양 으로 제작되었습니다 .
  • 컴파일러 테스트를 거칩니다 .
  • 컴파일러가 항상 신뢰할 수있는 것은 아닙니다 .

4

일반적으로 -O0에 매우 적합합니다. 실제로 컴파일러 버그가 의심되면 -O0과 사용하려는 수준을 비교합니다. 최적화 수준이 높을수록 위험이 커집니다. 일부는 일부러 의도적으로 문서화되어 있습니다. 나는 (많은 시간 동안 적어도 백) 많은 사람들을 만났지만 최근에는 훨씬 더 희귀 해지고 있습니다. 그럼에도 불구하고, 좋은 스펙 마크 수 (또는 마케팅에 중요한 다른 벤치 마크)를 추구함에있어 한계를 뛰어 넘는 유혹은 크다. 우리는 이름이없는 벤더가 명확하게 레이블이 지정된 컴파일 옵션 대신 괄호를 기본값으로 설정하기로 결정한 몇 년 전에 문제가있었습니다.

컴파일러 오류를 진단하고 스트레이 메모리 참조를 말하기가 어려울 수 있습니다. 다른 옵션을 사용하여 다시 컴파일하면 메모리 내에서 데이터 객체의 상대적 위치가 단순히 뒤섞 일 수 있으므로 소스 코드의 Heisenbug인지 버그인지 알 수 없습니다. 컴파일러. 또한 많은 최적화는 연산 순서에 따라 합법적으로 변경하거나 대수를 대수적으로 단순화하며 부동 소수점 반올림 및 언더 / 오버플로와 관련하여 다른 속성을 갖습니다. 이러한 효과를 REAL 버그와 분리하기는 어렵습니다. 이러한 이유로 하드 코어 부동 소수점 컴퓨팅은 어렵습니다. 버그와 수치 적 감도는 종종 풀기 어렵 기 때문입니다.


4

컴파일러 버그는 그리 드물지 않습니다. 가장 일반적인 경우는 컴파일러가 수락해야하는 코드에 대한 오류를보고하거나 컴파일러가 거부 된 코드를 수락하는 경우입니다.


불행히도 우리는 두 번째 종류의 버그를 볼 수 없습니다 : 코드 컴파일 = 모든 것이 정상입니다. 그래서 아마 반 (두 버그 클래스 간의 50 대 50의 분할 비율을 가정) 버그 사람들이 아니라 컴파일러 단위 테스트의 평균에 의해 발견되지 않습니다
지안루카 Ghettini

3

그렇습니다. 어제 ASP.NET 컴파일러에서 버그가 발생했습니다.

뷰에서 강력한 형식의 모델을 사용하는 경우 템플릿에 포함 할 수있는 매개 변수 수에 제한이 있습니다. 분명히 4 개의 템플릿 매개 변수를 사용할 수 없으므로 아래 두 예제 모두 컴파일러가 처리하기에는 너무 많은 양을 만듭니다.

ViewUserControl<System.Tuple<type1, type2, type3, type4, type5>>

그대로 컴파일하지 않지만 type5제거 하면 됩니다.

ViewUserControl<System.Tuple<MyModel, System.Func<type1, type2, type3, type4>>>

type4제거 하면 컴파일 됩니다.

참고 System.Tuple많은 과부하를 가지고 있으며, 16 매개 변수 (이 미친 내가 아는)까지 걸릴 수 있습니다.


3

컴파일러 자체에 버그가 발생한 적이 있습니까? 이것이 무엇이며 컴파일러 자체에 문제가 있다는 것을 어떻게 알았습니까?

예!

가장 기억에 남는 두 가지는 내가 처음 만난 두 사람입니다. 둘 다 약 1985-7 년에 680x0 Mac 용 Lightspeed C 컴파일러에있었습니다.

첫 번째는 어떤 상황에서는 정수 후행 증가 연산자가 아무 것도하지 않은 곳입니다. 즉, 특정 코드에서 "i ++"는 단순히 "i"에 대해 아무 것도하지 않았습니다. 나는 분해를 볼 때까지 머리를 뽑고 있었다. 그런 다음 방금 증가를 다른 방식으로 수행하고 버그 보고서를 제출했습니다.

두 번째는 조금 더 복잡했고 실제로 잘못 고려 된 "기능"이었습니다. 초기 맥은 저수준 디스크 작업을 수행하기위한 복잡한 시스템을 가지고있었습니다. 어떤 이유로 든 컴파일러가 객체 코드에서 디스크 작업 명령을 대신 생성하는 대신, 실행 파일을 작게 만드는 것과 관련이 없었습니다 .Lightspeed 컴파일러는 내부 함수를 호출하여 런타임에 디스크 작업을 생성했습니다. 스택에 대한 지시 사항으로 이동했습니다.

그것은 68000 CPU에서 훌륭하게 작동했지만 68020 CPU에서 동일한 코드를 실행하면 종종 이상한 일을합니다. 68020의 새로운 기능은 기본 명령 256 바이트 명령 캐시라는 것이 밝혀졌습니다. 초기에는 CPU 캐시가 있었지만 캐시가 "더러워"리필이 필요하다는 개념은 없었습니다. 모토로라의 CPU 디자이너들은 자체 수정 코드에 대해 생각하지 않았다고 생각합니다. 따라서 실행 순서에서 두 개의 디스크 작업을 충분히 가깝게 수행하고 Lightspeed 런타임이 스택의 동일한 위치에 실제 명령을 빌드 한 경우 CPU는 명령 캐시가 충돌했다고 생각하여 첫 번째 디스크 작업을 두 번 실행합니다.

다시 한 번, 디스어셈블러를 사용하여 파고 들었고, 저수준 디버거에서 많은 단일 스테핑을 수행했습니다. 내 해결 방법은 모든 디스크 작업 앞에 256 개의 "NOP"명령을 수행 한 함수를 호출하여 명령 캐시를 플러딩 (및 삭제)하는 것이 었습니다.

그 이후로 25 년 동안, 시간이 지남에 따라 점점 더 많은 컴파일러 버그가 발견되었습니다. 나는 몇 가지 이유가 있다고 생각합니다.

  • 컴파일러에 대한 검증 테스트 세트가 계속 증가하고 있습니다.
  • 최신 컴파일러는 일반적으로 둘 이상의 부분으로 나뉩니다. 그 중 하나는 플랫폼 독립적 인 코드를 생성합니다 (예 : 가상 CPU로 간주 할 수있는 LLVM의 타겟). 멀티 플랫폼 컴파일러에서 첫 번째 부분은 모든 곳에서 사용되므로 수많은 실제 테스트가 가능합니다.

자체 수정 코드를 피해야하는 이유 중 하나입니다.
Technophile

3

5.5 년 전에 Turbo Pascal에서 눈부신 오류가 발견되었습니다. 컴파일러의 이전 (5.0) 또는 다음 (6.0) 버전에 오류가 없습니다. 그리고 모퉁이가 아니기 때문에 (테스트가 쉽지 않은 테스트) (일반적으로 사용되지 않는 호출).

일반적으로, 취미 프로젝트가 아닌 상용 컴파일러 빌더는 매우 광범위한 QA 및 테스트 절차를 갖추고 있습니다. 그들은 그들의 컴파일러가 그들의 주력 프로젝트라는 것을 알고 있으며, 대부분의 다른 제품을 만드는 다른 회사를 보는 것보다 결함이 매우 나빠 보일 것입니다. 소프트웨어 개발자는 용서할 수없는 도구입니다. 툴 공급 업체를 통해 공급 업체의 수정을 기다리지 않고 대안을 찾을 수있을 것입니다. 예. 그렇지 않은 많은 다른 산업에서는 심각한 버그로 인해 컴파일러 제작자에 대한 잠재적 손실이 비디오 편집 소프트웨어 제작자보다 훨씬 큽니다.


2

-O0 및 -O2로 컴파일 할 때 소프트웨어의 동작이 다르면 컴파일러 버그를 발견 한 것입니다.

소프트웨어의 동작이 예상과 다른 경우 버그가 코드에있을 가능성이 있습니다.


8
반드시 그런 것은 아닙니다. C 및 C ++에는 불특정하고 정의되지 않은 동작이 많이 있으며, 이는 달의 최적화 수준이나 단계 또는 Dow Jones 인덱스의 움직임에 따라 합법적으로 달라질 수 있습니다. 이 테스트는보다 엄격하게 정의 된 언어로 작동합니다.
David Thornley

2

컴파일러 버그가 발생하지만 이상한 구석에있는 경향이 있습니다 ...

1990 년대에 Digital Equipment Corporation VAX VMS C 컴파일러에 이상한 버그가있었습니다.

(저는 당시 유행과 마찬가지로 벨트에 양파를 입고있었습니다)

for 루프 앞에있는 외부 세미콜론은 for 루프의 본문으로 컴파일됩니다.

f(){...}
;
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++){
     puts("hello");
  }
}

해당 컴파일러에서 루프는 한 번만 실행됩니다.

그것은 본다

f(){...}
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++) ;  /* empty statement for fun */

  {
     puts("hello");
  }
}

시간이 많이 걸렸습니다.

우리가 업무 경험에 영향을 미쳤던 PIC C 컴파일러의 이전 버전은 학생들이 우선 순위가 높은 인터럽트를 올바르게 사용한 코드를 생성 할 수 없었습니다. 2-3 년을 기다려 업그레이드해야했습니다.

MSVC 6 컴파일러는 링커에 멋진 버그가 있었으며 오류를 세분화하고 이유없이 죽습니다. 깨끗한 빌드는 일반적으로 그것을 고쳤습니다 (그러나 항상 한숨을 쉬지는 않습니다).


2

항공 전자 공학 소프트웨어와 같은 일부 도메인에서는 코드뿐만 아니라 하드웨어 및 컴파일러에 대한 인증 요구 사항이 매우 높습니다. 이 마지막 부분에는 Compcert 라는 공식적으로 검증 된 C 컴파일러를 만드는 것을 목표로하는 프로젝트가 있습니다. 이론적으로, 이런 종류의 컴파일러는 올만큼 신뢰할 수 있습니다.


1

나는 몇 가지 컴파일러 버그를 보았고, 몇 가지를보고했다 (특히 F #에서).

즉, 컴파일러를 작성하는 사람들은 일반적으로 컴퓨터 과학의 엄격한 개념에 매우 익숙하여 코드의 수학적 의미에 대해 실제로 의식하게되므로 컴파일러 버그는 드물다고 생각합니다.

그들 대부분은 아마도 람다 미적분학, 공식 검증, denotational semantics 등과 같은 것들에 매우 익숙 할 것입니다. 나 같은 평범한 프로그래머는 거의 이해할 수없는 것들입니다.

또한 일반적으로 컴파일러에서 입력에서 출력으로 상당히 간단한 매핑이 있으므로 프로그래밍 언어를 디버깅하는 것이 블로그 엔진을 디버깅하는 것보다 훨씬 쉽습니다.


1

얼마 전에 C # 컴파일러에서 버그를 발견했습니다 .C # 디자인 팀의 Eric Lippert가 버그가 무엇인지 어떻게 알았는지 알 수 있습니다 .

이미 주어진 답변 외에도 몇 가지 더 추가하고 싶습니다. 컴파일러 디자이너는 종종 매우 훌륭한 프로그래머입니다. 컴파일러는 매우 중요합니다. 대부분의 프로그래밍은 컴파일러를 사용하여 수행되므로 컴파일러의 품질이 중요합니다. 따라서 최고의 사람들을 배치하기 위해 컴파일러를 만드는 회사 (또는 적어도 좋은 사람들 : 컴파일러 디자인을 좋아하지 않을 수도 있음)는 회사의 이익에 가장 큰 관심을 기울입니다. Microsoft는 C 및 C ++ 컴파일러가 제대로 작동하기를 원하거나 회사의 나머지 작업을 수행 할 수 없습니다.

또한 복잡한 컴파일러를 작성하는 경우 함께 해킹 할 수 없습니다. 컴파일러의 논리는 매우 복잡하고 공식화하기 쉽습니다. 따라서 이러한 프로그램은 종종 매우 견고하고 일반적인 방식으로 작성되므로 버그가 줄어 듭니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.