7장: 컴파일러와의 협업

7장: 컴파일러와의 협업

컴파일러에 익숙해지면 컴파일러와 함께 정확성에 대한 책임을 공유함으로써 컴파일러를 팀원으로 받아들이고 컴파일러가 소프트웨어를 제대로 빌드하는데 도움이 되게 해야 된다

컴파일러에 대해 알아보기

컴파일러는 의심이 가면 물어보라 라는 일번적인 관용구를 따른다

약점: 정지 문제는 컴파일 시 알 수 있는 것을 제한한다

런타임 동안 어떤 일이 일어날지 정확히 말할 수 없는 이유를 정지문제(halting problem)라고 한다

일반적으로 프로그램은 근본적으로 예측이 불가능하다

컴파일러는 프로그램이 안전하다고 보장할 수 없는 경우 허용하지 않습니다 이를 보수적 분성(conservative analysis)이라고 한다

장점: 도달성 검증은 메서드의 반환을 보장한다

switch문의 경우 모든 case문이 컴파일러에 의해 도달 가능한지 검사한다 이를 완전 검사(exhaustive check)라고 한다

장점: 확정 할당은 초기화되지 않은 변수에 대한 접근을 막는다

확정 할당 분석(definite assignment analysis)은 변수가 초기화되지 않은 상태로 사용되는지 검사한다

장점: 접근 제어로 데이터 캡슐화를 지원한다

민감한 메서드가 있을 경우 접근 제어자를 사용하여 외부에서 접근하지 못하게 할 수 있다

장점: 타입(형) 검사기는 속성을 보증한다

  • 대여타입(Rust)
  • 다형성 타입 유추(Ocaml, F#)
  • 타입 클래스(하스켈)
  • 유니언 타입과 교차 타입(타입스크립트)
  • 종속 타입(coq 와 Agda)

약점: null을 역참조하면 애플리케이션이 손상된다

너무 적게 확인하는 것보다 너무 많이 확인하는 것이 낫다

약점: 산술 오류는 오버플로나 손상을 일으킨다

0으로 나누기 또는 나머지 연산 이를 산술적 오류(arithmetic error)라고 한다

약점: 아웃-오브-바운드 오류는 애플리케이션을 손상시킨다

범위네 있지 않은 인덱스에 접근하려고 하면 아웃-오브-바운드 오류(out-of-bounds error)가 발생한다

무한루프는 애플리케이션을 지연시킨다

컴파일러는 해당 값을 찾아 내지 못한다

약점: 교착 상태 및 경쟁 상태로 인해 의도하지 않은 동작이 발생한다

멀티스레딩에서 비롯됨 변경 가능한 데이터를 공유하는 여러 스레드가 있으면 문제의 홍수가 발생함

컴파일러 사용

소프트웨어 개발과 건축을 비유하긴 하는데 우리 분야에서 가장 해로운 비유 프로그래밍은 건축이 아닌 여러 단계의 커뮤니케이션

  • 컴퓨터와 의사소통(코드를 짤때)
  • 다른 개발자와 의사소통(코드를 읽을때)
  • 컴파일러와 의사소통(코드를 컴파일할때)

데이터 구조는 시간이 정지된 알고리즘이다

컴파일러 활용

  • 컴파일러 TODO 리스트로 안정성 확보
  • 순서 강제화를 이용한 안정성 확보
  • 캡슐화를 강제를 통한 안정성 확보
  • 컴파일러로 사용하지 않는 코드 감지
  • 확정 값을 통한 안정성 확보

컴파일러와 싸우지 말 것

  • 타입
  • 형 변환
  • 동적 타입
  • 런타임 타입
  • 게으름
  • 기본값
  • 상속
  • 처리를 강제하지 않은 예외
  • 아키텍처

컴파일러 신뢰하기

컴파일러에게 해준 만큼 돌려받을수 있다

컴파일러에게 불변속성 가르치기

이길수 없으면 같은 편으로 만들어라

컴파일러의 경고에 주의를 기울일 것

정보 피로(alarm fatigue)는 경고를 무시하게 만든다

컴파일러만 신뢰할 것

만일 당신이 이 방에서 가장 똑똑한 사람이라면 당신은 잘못된 방에 있는 것이다

참조