형식 안전
Type safety유형 시스템 |
---|
일반적인 개념 |
주요 카테고리 |
마이너 카테고리 |
컴퓨터 과학에서 유형 안전성과 유형 건전성은 프로그래밍 언어가 유형 오류를 방지하거나 방지하는 정도를 말합니다.타입 세이프티는 컴퓨터 언어 설비의 속성으로 간주되는 경우가 있습니다.즉, 일부 설비는 타입 세이프이며 그 사용으로 인해 타입 에러가 발생하지 않는 반면, 같은 언어의 다른 설비는 타입 세이프이며, 이를 사용하는 프로그램에서는 타입 에러가 발생할 수 있습니다.특정 프로그래밍 언어에 의해 유형 오류로 분류되는 동작은 일반적으로 적절한 데이터 유형이 아닌 값에 대해 연산을 수행하려고 시도했을 때 발생합니다. 예를 들어, 이 경우의 처리 방법에 대한 정의가 없는 경우 정수에 문자열을 추가하는 것입니다.이 분류는 부분적으로 의견에 근거한다.
유형 적용은 정적, 컴파일 시 잠재적 오류 캐치 또는 동적 유형 정보를 런타임에 값과 관련지어 임박한 오류를 검출하기 위해 필요에 따라 참조하거나 둘 다 조합할 수 있습니다.동적 유형 적용에서는 정적 적용에서는 유효하지 않은 프로그램을 실행할 수 있습니다.
정적(컴파일 시간) 유형 시스템의 맥락에서 유형 안전성은 일반적으로 표현의 최종 값이 해당 표현의 정적 유형의 정규 멤버가 된다는 보증을 수반합니다.정확한 요건은 이것보다 더 미묘합니다.예를 들어 복잡성에 대해서는 서브타이핑이나 다형성을 참조해 주세요.
정의들
타입 세이프 코드는, 액세스 할 수 있는 메모리 위치에만 액세스 합니다.(이 설명에서는 타입 세이프티는 특히 메모리 타입의 안전성을 나타내며, 넓은 관점에서 타입 세이프티와 혼동해서는 안 됩니다.)예를 들어 type-safe 코드는 다른 개체의 개인 필드에서 값을 읽을 수 없습니다.
Robin Milner는 다음과 같은 슬로건을 제공하여 안전 유형을 설명하였습니다.
- 잘 입력된 프로그램은 "잘못"[1]될 수 없습니다.
이 슬로건의 적절한 공식화는 특정 언어에 사용되는 공식 의미론의 스타일에 따라 달라집니다.표현적 의미론에서 type safety는 예를 들어 type이 θ인 식의 값이 θ에 대응하는 집합의 진정한 멤버임을 의미한다.형식적인 형식적 유형 이론의 안전 정의는 대부분의 프로그래머가 이해하는 것보다 훨씬 강력하다.
1994년 Andrew Wright와 Matthias Felleisen은 운영 의미론에 의해 정의된 언어로 형식 안전에 대한 표준 정의 및 입증 기술을 공식화했다.이 접근법에 따라 유형 안전성은 프로그래밍 언어의 의미론 두 가지 특성에 의해 결정된다.
- (종류-) 보존 또는 대상 감소
- 프로그램의 "잘 유형화"("유형성")는 언어의 전환 규칙(평가 규칙 또는 축소 규칙)에 따라 변하지 않습니다.
- 진보.
- 잘 입력된 (표준) 프로그램은 "고정"되지 않습니다.즉, 프로그램 내의 표현식이 값으로 평가되거나 변환 규칙이 있음을 의미합니다.즉, 프로그램은 더 이상의 전환이 불가능한 정의되지 않은 상태가 되지 않습니다.
이러한 속성은 진공상태에서 존재하지 않는다; 그들은 그들이 기술하는 프로그래밍 언어의 의미론과 연결되어 있다; 그리고 "잘 타이핑된" 프로그램의 개념은 프로그래밍 언어의 정적 의미론의 일부이고 "막힘" (또는 "잘못됨") i의 개념이기 때문에 이러한 기준에 맞는 다양한 언어의 큰 공간이 있다.는 동적 의미론의 속성입니다.
Vijay Saraswat은 다음과 같은 정의를 제공합니다.
- 언어의 데이터에 대해 실행할 수 있는 조작이 [2]데이터의 유형에 의해 허가된 조작뿐이라면 언어는 타입 세이프입니다.
다른 형태의 안전과의 관계
형식 안전은 궁극적으로 다음과 같은 다른 문제를 배제하는 것을 목표로 한다.
- 불법 영업 방지예를 들어, 다음과 같은 식을 식별할 수 있습니다.
3 / "Hello, World"
산술 규칙에는 정수를 문자열로 나누는 방법이 지정되어 있지 않기 때문에 유효하지 않습니다. - 메모리 안전성
- 다른 유형의 의미론에서 발생하는 논리 오류입니다.예를 들어 인치와 밀리미터는 모두 정수로 저장할 수 있지만 서로 대체하거나 추가해서는 안 됩니다.유형 시스템은 두 가지 유형의 정수를 적용할 수 있습니다.
타입 세이프 언어 및 타입 세이프 언어
형식 안전은 일반적으로 학술 프로그래밍 언어 연구에서 제안된 완구 언어(즉, 난해한 언어)의 요건이다.반면에, 많은 언어들은 종종 수천 건의 사례를 확인해야 하기 때문에, 인간이 만든 유형의 안전 증명에는 너무 크다.그럼에도 불구하고, 엄격하게 정의된 의미론을 가진 표준 ML과 같은 일부 언어는 유형 [3]안전의 정의를 충족하는 것으로 입증되었다.Haskell과 같은 일부 다른 언어들은 특정 "회피" 기능이 사용되지 않는 한 형식 안전의 정의를 충족하는 것으로 여겨진다[discuss](예: Haskell의 언어).안전하지 않은 퍼포먼스I/O가 가능한 통상적인 제한된 환경으로부터 "탈출"하기 위해 사용되는 IO는 타입 시스템을 우회하므로 타입의 안전을 해치는 데 사용될 수 있습니다.)[4]타입 펀닝은 이러한 "회피" 기능의 또 다른 예입니다.언어 정의의 속성에 관계없이 실행 시 구현 오류 또는 다른 언어로 작성된 링크된 라이브러리로 인해 특정 오류가 발생할 수 있습니다. 이러한 오류는 특정 상황에서 특정 구현 유형을 안전하지 않게 만들 수 있습니다.Sun의 Java 가상 머신의 초기 버전은 이러한 종류의 [2]문제에 취약했습니다.
강자와 약자의 타이핑
프로그래밍 언어는 구어체적으로 강력한 유형 또는 약한 유형(또한 느슨한 유형)으로 분류되어 유형 안전의 특정 측면을 참조합니다.1974년, 리스코프와 질레스는 강한 타입의 언어를 "객체가 호출함수에서 호출함수로 전달될 때마다 그 유형은 호출함수에 [5]선언된 유형과 호환되어야 한다"고 정의했다.1977년에 Jackson은 "강력하게 타이핑된 언어에서는 각 데이터 영역이 고유한 유형을 가지며 각 프로세스는 이러한 [6]유형의 관점에서 통신 요구사항을 명시할 것입니다."라고 썼다.반면, 약하게 입력된 언어는 예측할 수 없는 결과를 생성하거나 암묵적인 유형 [7]변환을 수행할 수 있습니다.
메모리 관리 및 유형 안전성
타입 세이프티는 메모리 세이프티와 밀접하게 관련되어 있습니다.예를 들어 일부 비트 패턴을 허용하지만 다른 비트 패턴은 허용하지 않는 t를 가진 언어의 구현에서는 t\t의 멤버를 나타내지 않는 비트 패턴을 t의 데드 변수에 쓸 수 있으므로 ty가 발생합니다.변수를 읽을 때 pe 오류가 발생합니다.반대로 언어가 메모리 안전하다면 임의 정수를 포인터로 사용할 수 없으므로 별도의 포인터 또는 참조 유형이 있어야 합니다.
최소한의 조건으로서 타입 세이프 언어는 다른 타입의 할당에 걸쳐 포인터를 달지 않도록 해야 합니다.그러나 대부분의 언어는 메모리의 안전성이나 치명적인 장애의 예방을 위해 반드시 필요하지 않은 경우에도 프로그래머에 의해 정의된 추상 데이터 유형을 적절하게 사용합니다.할당에는 해당 내용을 설명하는 유형이 지정되며, 이 유형은 할당 기간 동안 고정됩니다.이를 통해 유형 기반 별칭 분석을 통해 서로 다른 유형의 할당이 구별된다는 것을 추론할 수 있습니다.
대부분의 타입 세이프 언어에서는 가비지 컬렉션을 사용합니다.Pierce는 "명시적인 할당 해제 조작이 존재하는 경우, 포인터가 [8]흔들리기 때문에 타입의 안전성을 달성하는 것은 매우 어렵다"고 말합니다.그러나 Rust는 일반적으로 타입 세이프로 간주되며 가비지 수집 대신 차입 체커를 사용하여 메모리 안전을 확보합니다.
객체 지향 언어로 안전 유형 지정
객체 지향 언어에서 유형 안전성은 일반적으로 유형 시스템이 있다는 사실에 내재한다.이것은 클래스 정의로 표현됩니다.
클래스는 기본적으로 클래스에서 파생된 객체의 구조와 API를 이러한 객체를 처리하기 위한 계약으로 정의합니다.새 객체가 생성될 때마다 해당 계약을 준수합니다.
특정 클래스에서 파생된 객체를 교환하거나 특정 인터페이스를 구현하는 각 함수는 계약을 준수합니다.따라서 해당 함수에서 해당 객체에서 허용되는 작업은 객체가 구현하는 클래스의 메서드에 의해 정의된 작업만 됩니다.이렇게 하면 개체의 무결성이 유지됩니다.[9]
이에 대한 예외는 객체 구조의 동적 수정이나 클래스 메서드 정의에 의해 부과된 제약을 극복하기 위해 객체의 내용을 수정하는 반사를 사용할 수 있는 객체 지향 언어입니다.
안전 문제를 특정 언어로 입력
아다
Ada는 임베디드 시스템, 디바이스 드라이버 및 기타 형태의 시스템 프로그래밍에 적합하도록 설계되었으며, 또한 타입 세이프 프로그래밍을 장려하도록 설계되었습니다.이러한 모순되는 목표를 해결하기 위해 Ada는 type-unsafety를 보통 이름이 Unchecked_ 문자열로 시작하는 특정 특수 구성 집합으로 제한합니다.이 유닛에 pragma Pure를 적용함으로써 Ada 텍스트 유닛에서 Unit of Allocation을 효과적으로 금지할 수 있습니다.프로그래머는 매우 신중하게 필요한 경우에만 Unchecked_구조를 사용할 것으로 예상됩니다.사용하지 않는 프로그램은 타입 세이프입니다.
SPARK 프로그래밍 언어는 Ada의 서브셋으로 잠재적인 모호성과 불안감을 해소하는 동시에 이용 가능한 언어 기능에 정적으로 체크된 계약을 추가합니다.SPARK는 실행 시 할당을 완전히 거부함으로써 포인터의 행잉 문제를 회피합니다.
Ada2012는 언어 자체에 정적 체크 계약을 추가합니다(유형 불변성뿐만 아니라 사전 및 사후 조건의 형태로).
C
C 프로그래밍 언어는 제한된 컨텍스트에서 타입 세이프입니다.예를 들어, 명시적 캐스트를 사용하지 않는 한, 한 유형의 구조에 대한 포인터를 다른 유형의 구조에 대한 포인터로 변환하려고 하면 컴파일 시간 오류가 발생합니다.그러나 많은 매우 일반적인 조작은 타입 세이프가 아닙니다.예를 들어, 정수를 인쇄하는 일반적인 방법은 다음과 같습니다.printf("%d", 12)
, 여기서%d
말한다printf
런타임에 정수 인수를 예상합니다. (예:printf("%s", 12)
이는 문자열에 대한 포인터를 예상하도록 함수에 지시하고 정수 인수를 제공하는 것으로 컴파일러에 의해 받아들여질 수 있지만 정의되지 않은 결과를 생성합니다.)이는 일부 컴파일러(gcc 등)가 printf 인수와 형식 문자열 간의 유형 대응을 체크함으로써 부분적으로 완화됩니다.
또한 C는 Ada와 마찬가지로 지정되지 않거나 정의되지 않은 명시적 변환을 제공합니다. 또한 Ada와 달리 이러한 변환을 사용하는 관용구는 매우 일반적이며 C에게 안전하지 않은 유형의 평판을 제공하는 데 도움이 되었습니다.예를 들어, 힙에 메모리를 할당하는 표준 방법은 다음과 같은 메모리 할당 함수를 호출하는 것입니다.malloc
필요한 바이트 수를 나타내는 인수를 지정합니다.함수는 입력되지 않은 포인터를 반환합니다(유형).void *
발신측 코드가 명시적으로 또는 암묵적으로 적절한 포인터 타입에 캐스트 할 필요가 있습니다.C의 사전 표준화 구현에서는 이를 위해 명시적인 캐스트가 필요했습니다.따라서 코드는(struct foo *) malloc(sizeof(struct foo))
관행이 [10]되었습니다.
C++
보다 안전한 타입 코드를 촉진하는 C++의 기능:
- 새 연산자는 피연산자를 기준으로 유형의 포인터를 반환하는 반면 malloc은 void 포인터를 반환합니다.
- C++ 코드는 가상 함수와 템플릿을 사용하여 보이드 포인터 없이 다형성을 달성할 수 있습니다.
- 런타임 유형 확인을 수행하는 동적 주조와 같은 주조 작업자가 더 안전합니다.
- C++11 강력한 형식의 열거형은 정수 또는 다른 열거형 형식과 암묵적으로 변환할 수 없습니다.
- C++ 명시적 생성자 및 C++11 명시적 변환 연산자는 암묵적 유형 변환을 방지합니다.
C#
C#은 타입 세이프입니다(단, 스태틱타입 세이프는 아닙니다).이것은 입력되지 않은 포인터를 지원하지만 컴파일러 수준에서 금지될 수 있는 "unsafe" 키워드를 사용하여 액세스해야 합니다.런타임 캐스트 검증을 기본적으로 지원합니다.캐스트가 유효하지 않은 경우 null 참조를 반환하는 "as" 키워드를 사용하거나, 캐스트가 유효하지 않은 경우 예외를 발생시키는 C 스타일 캐스트를 사용하여 캐스트를 검증할 수 있습니다.C Sharp 변환 연산자를 참조하십시오.
오브젝트 타입(다른 타입이 모두 파생된 것)에 과도하게 의존하면 C# 타입 시스템의 목적을 저하시킬 위험이 있습니다.일반적으로 C++의 템플릿이나 Java의 범용과 마찬가지로 범용을 위해 오브젝트 참조를 포기하는 것이 좋습니다.
자바
Java 언어는 유형 안전을 위해 설계되었습니다.Java의 모든 것은 개체 내부에서 발생하며 각 개체는 클래스의 인스턴스입니다.
유형 안전 시행을 구현하려면 사용 전에 각 개체를 할당해야 합니다.Java는 원시 유형을 사용할 수 있지만 적절하게 할당된 개체 내에서만 사용할 수 있습니다.
때로는 유형 안전성의 일부가 간접적으로 구현되기도 한다. 예를 들어, BigDecimal 클래스는 임의의 정밀도의 부동 소수점 번호를 나타내지만 유한한 표현으로 표현될 수 있는 숫자만 처리한다.BigDecimal.divide() 연산은 새로운 개체를 BigDecimal로 표현되는 두 숫자의 나눗셈으로 계산합니다.
이 경우, 예를 들어 1/3=0.3333...과 같이 나눗셈에 유한한 표현이 없는 경우, divide() 메서드는 반올림 모드가 정의되지 않은 경우 예외를 발생시킬 수 있습니다.그러므로 언어보다는 라이브러리는 객체가 클래스 정의에 내재된 계약을 존중하는 것을 보증한다.
표준 ML
표준 ML은 엄격하게 정의된 의미론을 가지고 있으며 타입 세이프한 것으로 알려져 있습니다.그러나 뉴저지 표준 ML(SML/NJ), 구문 변형 Mythryl 및 MLton을 포함한 일부 구현에서는 안전하지 않은 작업을 제공하는 라이브러리를 제공합니다.이러한 기능들은 종종 이러한 구현의 외부 함수 인터페이스와 함께 특정 방식으로 레이아웃된 데이터를 필요로 하는 비ML 코드(예: C 라이브러리)와 상호 작용하기 위해 사용됩니다.다른 예로는 사용자가 입력한 ML 코드를 실행하기 위해 안전하지 않은 작업을 사용해야 하는 SML/NJ 인터랙티브 탑레벨이 있습니다.
모듈라-2
Modula-2는 안전하지 않은 설비를 안전하지 않은 것으로 명시적으로 표시해야 하는 설계 철학을 가진 강력한 유형의 언어이다.이는 이러한 설비를 사용하기 전에 Import해야 하는 SYSTEM이라는 빌트인 의사 라이브러리로 "이동"함으로써 실현됩니다.따라서 이러한 설비를 사용할 때 이를 확인할 수 있다.불행하게도, 이것은 원래 언어 보고서와 그 [11]구현에서 결과적으로 구현되지 않았다.이전 [12]가져오기 없이 사용할 수 있는 활자 주조 구문 및 변형 레코드(Pascal에서 상속됨)와 같은 안전하지 않은 설비가 남아 있었습니다.이러한 패실리티를 SYSTEM 유사 모듈로 이행하는 데 어려움이 있었던 것은 ID만 Import할 수 있고 구문은 Import할 수 없기 때문에 Import할 수 있는 패실리티의 ID가 없었기 때문입니다.
수입품 시스템.; (* 안전하지 않은 특정 시설의 사용을 허용합니다.* ) VAR 단어 : 시스템..단어; 주소 : 시스템..주소.; 주소 := 시스템..ADR(단어); (* 단, type cast 구문은 Import 없이 사용할 수 있습니다*). VAR i : 정수; n : 주요; n := 주요(i); (* 또는 *) i := 정수(n);
ISO Modula-2 표준은 타입 캐스트 구문을 의사 모듈 SYSTEM에서 Import해야 하는 CAST라는 함수로 변경하여 타입 캐스트 설비에 대해 이를 수정했습니다.그러나 변종 기록과 같은 다른 안전하지 않은 시설은 의사 모듈 [13]SYSTEM에서 가져오지 않고도 사용할 수 있었다.
수입품 시스템.; VAR i : 정수; n : 주요; i := 시스템..출연자들(정수, n); (* ISO 모듈라-2의 유형 주조 *)
최근의 언어 수정은 원래의 디자인 철학을 엄격하게 적용했다.첫째, 유사 모듈 SYSTEM은 그곳에서 가져온 설비의 안전하지 않은 특성을 보다 명확하게 하기 위해 안전하지 않은 모듈로 이름을 변경했습니다.그런 다음 (바리안트 레코드 등)를 완전히 삭제하거나 의사 모듈 SAUFERT로 이동한 나머지 모든 안전하지 않은 설비.Import할 수 있는 식별자가 없는 설비에 대해서는, 이네이블 식별자가 도입되었습니다.이러한 퍼실리티를 이노블로 만들려면 대응하는 이노블 ID를 의사 모듈 UNEFACER에서 Import해야 합니다.안전하지 않은 [12]설비는 안전하지 않은 언어에서 가져올 필요가 없습니다.
수입품 안전하지 않다; VAR i : 정수; n : 주요; i := 안전하지 않다.출연자들(정수, n); (* Modula-2 개정 2010*의 형식 캐스팅) 부터 안전하지 않다 수입품 FFI; (* 외부 기능 인터페이스 패실리티의 식별자를 유효하게 합니다*) <*FFI="C"*> (*C에 대한 외부 기능 인터페이스용 플러그마*)
파스칼
Pascal은 몇 가지 유형의 안전 요건을 가지고 있으며, 그 중 일부는 일부 컴파일러에 보관되어 있습니다.파스칼 컴파일러가 "엄격한 타이핑"을 지시하는 경우, 두 변수는 호환성이 있거나(예를 들어 정수를 실제로 변환) 동일한 하위 유형에 할당되지 않는 한 서로 할당할 수 없습니다.예를 들어, 다음과 같은 코드 fragment가 있는 경우:
유형 2종류 = 기록. I: 정수; Q: 진짜; 끝.; 듀얼 타입 = 기록. I: 정수; Q: 진짜; 끝.; 변화하다 T1, T2: 2종류; D1, D2: 듀얼 타입;
엄밀한 입력에서는 TwoTypes로 정의된 변수는 DualTypes와 호환되지 않습니다(사용자 정의 유형의 컴포넌트가 동일해도 동일하지 않기 때문에).및 할당:T1 := D2;
불법입니다.의 할당T1 := T2;
정의되어 있는 서브타입이 동일하기 때문에 합법적입니다.단, 다음과 같은 과제는T1.Q := D1.Q;
합법적일 겁니다
일반적인 리스프
일반적으로 공통 리스프는 안전한 언어입니다.Common Lisp 컴파일러는 타입의 안전성을 정적으로 증명할 수 없는 동작의 동적 체크를 삽입합니다.그러나 프로그래머는 프로그램을 낮은 수준의 동적 유형 검사로 [14]컴파일해야 한다고 지시할 수 있습니다.이러한 모드로 컴파일된 프로그램은 타입 세이프로 간주할 수 없습니다.
C++의 예
다음 예시는 C++ 캐스트 연산자가 잘못 사용될 경우 어떻게 유형 안전성을 해칠 수 있는지를 보여줍니다.첫 번째 예시는 기본 데이터 유형을 잘못 캐스팅하는 방법을 보여 줍니다.
#실패하다 <iostream> 사용. 네임스페이스 표준; 인트 주된 () { 인트 동작하다 = 5; // 정수값 흘러가다 기능하다 = 재해석_캐스트< >흘러가다&>(동작하다); // 비트 패턴 재해석 외치다 << > 기능하다 << > 끝; // 정수를 플로트로 출력 돌아가다 0; }
이 예에서는,reinterpret_cast
는 컴파일러가 정수에서 부동소수점 [15]값으로 안전하게 변환하는 것을 명시적으로 금지합니다.프로그램이 실행되면 가비지 부동소수점 값이 출력됩니다.대신 글을 쓰면 문제를 피할 수 있었다.float fval = ival;
다음 예시는 오브젝트 참조가 잘못 다운캐스트되는 방법을 보여 줍니다.
#실패하다 <iostream> 사용. 네임스페이스 표준; 학급 부모 { 일반의: 가상 ~부모() {} // RTI의 가상 소멸자 }; 학급 차일드 1 : 일반의 부모 { 일반의: 인트 a; }; 학급 차일드2 : 일반의 부모 { 일반의: 흘러가다 b; }; 인트 주된 () { 차일드 1 c1; c1.a = 5; 부모 & p = c1; // 업캐스트는 항상 안전 차일드2 & c2 = static_cast< >차일드2&>(p); // 무효 다운캐스트 외치다 << > c2.b << > 끝; // 가비지 데이터를 출력합니다. 돌아가다 0; }
두 개의 자식 클래스는 서로 다른 유형의 구성원을 가집니다.부모 클래스 포인터를 자식 클래스 포인터로 다운캐스트할 때 결과 포인터가 올바른 유형의 유효한 개체를 가리키지 않을 수 있습니다.이 예에서는 가비지 값이 인쇄됩니다.교체하면 문제를 방지할 수 있었습니다.static_cast
와 함께dynamic_cast
무효 [16]캐스팅에 예외를 두는 것입니다.
「 」를 참조해 주세요.
메모들
- ^ Milner, Robin (1978), "A Theory of Type Polymorphism in Programming", Journal of Computer and System Sciences, 17 (3): 348–375, doi:10.1016/0022-0000(78)90014-4
- ^ a b Saraswat, Vijay (1997-08-15). "Java is not type-safe". Retrieved 2008-10-08.
- ^ 표준 ML. Smlnj.org2013-11-02에 취득.
- ^ "System.IO.Unsafe". GHC libraries manual: base-3.0.1.0. Archived from the original on 2008-07-05. Retrieved 2008-07-17.
- ^ Liskov, B; Zilles, S (1974). "Programming with abstract data types". ACM SIGPLAN Notices. 9 (4): 50–59. CiteSeerX 10.1.1.136.3043. doi:10.1145/942572.807045.
- ^ Jackson, K. (1977). "Parallel processing and modular software construction". Design and Implementation of Programming Languages. Lecture Notes in Computer Science. 54: 436–443. doi:10.1007/BFb0021435. ISBN 3-540-08360-X.
- ^ "CS1130. Transition to OO programming. – Spring 2012 --self-paced version". Cornell University, Department of Computer Science. 2005. Archived from the original on 2005. Retrieved 2015-11-23.
- ^ Pierce, Benjamin C. (2002). Types and programming languages. Cambridge, Mass.: MIT Press. p. 158. ISBN 0-262-16209-1.
- ^ 따라서 유형 안전도 좋은 클래스 정의의 문제입니다. 객체의 내부 상태를 수정하는 공용 방법은 객체의 신뢰성을 보존해야 합니다.
- ^ Kernighan; Dennis M. Ritchie (March 1988). The C Programming Language (2nd ed.). Englewood Cliffs, NJ: Prentice Hall. p. 116. ISBN 978-0-13-110362-7.
In C, the proper method is to declare that malloc returns a pointer to void, then explicitly coerce the pointer into the desired type with a cast.
- ^ Niklaus Wirth (1985). Programming in Modula-2. Springer Verlag.
- ^ a b "The Separation of Safe and Unsafe Facilities". Retrieved 24 March 2015.
- ^ "ISO Modula-2 Language Reference". Retrieved 24 March 2015.
- ^ "Common Lisp HyperSpec". Retrieved 26 May 2013.
- ^ http://en.cppreference.com/w/cpp/language/reinterpret_cast
- ^ http://en.cppreference.com/w/cpp/language/dynamic_cast
레퍼런스
- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. ISBN 978-0-262-16209-8.
- "Type Safe". Portland Pattern Repository Wiki.
- Wright, Andrew K.; Matthias Felleisen (1994). "A Syntactic Approach to Type Soundness". Information and Computation. 115 (1): 38–94. doi:10.1006/inco.1994.1093.
- Macrakis, Stavros (April 1982). "Safety and power". ACM SIGSOFT Software Engineering Notes. 7 (2): 25–26. doi:10.1145/1005937.1005941. S2CID 10426644.