2009-03-03 3 views
8

포인터를 이해하고 C# 코드에서 사용할 필요가 거의 없습니다. 내 질문은 : 코드 블록에 "안전하지 않은"상태를 명시해야하는 이유는 무엇입니까? 또한 "안전하지 않은"코드를 허용하기 위해 컴파일러 옵션을 변경해야하는 이유는 무엇입니까?C# : 명시 적으로 "안전하지 않은"/ 컴파일러 옵션을 명시하는 이점

결론 : 무엇 CLR (또는 언어 사양)에서 우리가 원하는 때마다 그래서 우리가 (많은 C 및 C++ 등) "안전하지 않은"입력하고 컴파일러 옵션을 변경하지 않고 포인터를 사용할 수 있습니다 ?

설명 : "안전하지 않은"코드와 "안전한"코드가 무엇인지 알고 있습니다. 그것은 단지 이러한 기능을 사용할 수 있도록하기 위해 왜 우리가 모든 추가 작업을해야하는지에 대한 질문입니다.

답변

9

제목이 here 인 C# Creator Anders Hejlsberg와의 인터뷰가 있습니다. 기본적으로 정확히 @Marc Gravell이 말한 바 : typesafety first, 명시 적 선언으로 안전하지 못함.

귀하의 질문에 답해주십시오. CLR에서는 아무 것도 없습니다. 유형을 다룰 때 안전 장갑으로 작업 할 수 있도록 설계된 언어 관용구입니다. 장갑을 벗고 싶다면 선택하는 것이지만 장갑을 벗는 적극적인 선택을해야합니다.

편집 : 명확한 설명을 위해

: 나는 은 "안전하지 않은"과 "안전"코드가 무엇인지 알고있다. 단지 이 기능을 사용할 수 있으려면 왜 추가 작업을해야합니까 (별다른 도움이되지 않습니다) .

인터뷰에서 언급했듯이 명시 적 디자인 결정이었습니다. C#은 근본적으로 Java의 진화이며 Java에서는 포인터가 전혀 없습니다. 그러나 디자이너는 포인터를 허용하려고했습니다. 그러나 C#은 일반적으로 Java 개발자를 데려 오기 때문에 의 기본값 인의 동작이 Java와 유사해야 (즉, 포인터가없는 경우) 명시 적 선언을 통해 포인터를 사용할 수있는 것이 가장 좋을 거라고 생각했습니다.

"추가 작업"은 사용자가 작업하기 전에 수행중인 작업에 대해 생각하도록합니다. 명시 적으로 말하면, 적어도 다음을 고려해야합니다. "내가 왜 이러는거야? 실제로은 참조 유형이 충분할 때 포인터가 필요합니까?"

7

대부분 검증 가능합니다. unsafe이라고 말하면 장갑은 꺼져 있습니다. 시스템에서 더 이상 코드가 아무렇게나 작동하지 않을 수도 있습니다. 대부분의 경우 안전 지대에 머무르는 것이 좋습니다.

이것은 부분 신뢰 (addins 등)로 더 눈에 띄게되지만 일반 코드에서는 여전히 유용합니다.

+0

기본적으로 C++에서 작성하는 것이 훨씬 쉬운 것처럼 실수를 저지르는 것을 시도하는 MS가 있습니까? – Inisheer

+1

낮은 수준의 API 호출을하거나 포인터 산술을 사용하거나 다른 부적절한 작업을 수행하는 MS : C# 코드에서 unsafe 키워드로 표시된 블록 안에 배치해야합니다. – VBNight

+0

# 보낸 사람 MS : 경우에 따라 안전하지 않은 코드는 배열 범위 검사를 제거하여 응용 프로그램의 성능을 향상시킬 수 있습니다. – VBNight

1

그래서 등, 좋은 습관을 & 보안을 육성

1

관리자 권한없이 웹 서비스에서 실행되지 않습니다 어떤 코드를 즉시 명백한입니다. 어셈블리에서 안전하지 않은 블록을 사용할 때마다 NativeCode 권한이 스택에서 요구됩니다. 이것은 물론 암묵적으로 수행 될 수 있지만, 우리는 또한 private 키워드를 완전히 제거 할 수 없었습니까? 개발자가 안전하지 않은 코드를 사용하기 전에 특별히 요구하도록 개발자에게 강요하는 것이 바람직하다고 생각합니다.

2

안전하지 않은 블록을 사용하면 코드를 확인할 수 없게 만드는 효과가 있습니다. 이를 위해서는 특정 권한이 필요하며 출력에 허용하고 싶지 않을 수도 있습니다 (특히 공유 소스 환경에있는 경우). 따라서 컴파일러에서 스위치를 허용하지 않는 스위치가 있습니다.

2

반대 의견에서 생각해보십시오. 안전하지 않은 것으로 표시되지 않았기 때문에 대부분의 코드가 기본적으로 "안전함"이라고 유추 할 수 있습니다. 그렇다면 "안전하다"는 것은 무엇을 의미합니까? .Net 코드의 경우 다음이 포함됩니다 (이에 국한되지 않음).

  • 가비지 수집기는 평소와 같이 비즈니스를 수행 할 수 있습니다.
  • 특정 유형에 대한 참조가 일 경우은 해당 유형의 개체 (또는 null)를 나타냅니다.
  • 코드는 .Net 신뢰/보안 요구 사항을 준수 함이 보장됩니다.
  • 코드는 직접적으로 자체 AppDomain 외부의 메모리를 만지지 않도록 수학적으로 입증되었습니다. 사소한 것처럼 보일 수도 있지만 동일한 응용 프로그램에 여러 AppDomains가있는 경우를 상상해보십시오. 프로그래머는 논리적으로 분리하여 자신있게 처리 할 수 ​​있습니다.

포인터를 사용할 때마다 이러한 보증을 위반할 가능성이 있습니다. 따라서 코드를 안전하지 않은 것으로 표시하면 이러한 보호가 포기됩니다.

1

안전 코드와 안전하지 않은 코드의 가장 큰 차이점은 .NET의 가비지 수집기가 안전하지 않은 코드에 도달 할 수 없다는 것입니다. 자동 GC는 .net의 모국어의 큰 부분이며, 경계를 넘어 서면 코드에 대해 많은 것을 변경할 수 있습니다.

포인터는 특히 GC 참조없이 힙에 개체를 만들 수 있도록합니다. 따라서 코드가 "안전하지 않은"것으로 표시되어야하는 또 다른 중요한 이유가 있습니다. 메모리 누수가 어디에서 발생하는지 파악하기가 쉽습니다.

3

실제로 CLR은 안전하지 않은 스위치 나 키워드에 대한 요구 사항을 전혀 만들지 않습니다. 실제로 C++/CLI (CLR에서 실행되는 C++ 언어)에는 그러한/안전하지 않은 스위치가 없으며 CLR에서 포인터를 자유롭게 사용할 수 있습니다.

그래서 "포인터가 사용되기 전에 C#에서 사용/안전하지 않아야하는 이유는 무엇입니까?"라는 질문을 다시 표현할 것입니다. 그리고 그 질문에 대한 답은 여기에 주어진 다른 대답에 명시된 바와 같습니다 : 사용자가 CLR에서 완전 신뢰 모드 미만으로 실행할 수있는 능력을 상실한다는 의식적 결정을하도록 도와줍니다. C++은 사실상 CLR에 대한 완전한 신뢰가 필요합니다. C# 은 완전 신뢰가 필요한 코드를 호출 할 때마다 또는 포인터를 사용할 때마다이 될 수 있습니다.

+0

바로. 나는 "최종선"부분을 더 일찍 바꾸었다. 나는 C++/CLI를 꽤 자주 사용하며, 사실 C#에 관한이 질문을하는 이유입니다. – Inisheer

2

요약하면 .NET은 사용자가 의도를 진술하기를 원합니다.

확실히 컴파일러는 "안전하지 않은"플래그의 필요성을 추측 할 수 있습니다. 그러나 설계자는 그것을 의도적 인 결정으로하기를 원합니다.

  • 휴식 없이는 스위치 케이스
  • 액세스 권한이없는 수준 같은 "대중"으로 "섹션"(: C 마커 ++ 나에게

    , 그것은 C#에서 구문 요구 사항의 수에 가깝다) "VAR"을 사용하여

  • 없는 클래스 필드

패턴이 다른 영향을 미치지 실수로 이동하거나 한 가지를 변경하지 말아야한다는 것입니다. 이유 안에서, 그들은 "발에서 자신을 쏘지"못하게하고 싶습니다.

위대한 유익한 답변이 많이 있습니다 — 아마도이 질문에 대한 더 많은 이동합니다.