2009-12-07 4 views

답변

33

다른 사람들이 언급했듯이 "안전하지 않은"블록의 거의 모든 것이 구현 정의 동작을 산출 할 수 있습니다. 안전하지 않은 블록을 악용하면 런타임 자체를 구성하는 코드 바이트를 변경할 수 있으므로 모든 베팅은 해제됩니다.

정수 나누기의 대소 문자에는 구현 정의 동작이 있습니다.

예외를 throw하고 결코 catch하지 않으면 구현이 정의 된 동작이 발생합니다. 프로세스를 종료하고 디버거를 시작합니다.

구현 결정 동작을하는 코드를 강제로 내보내는 C#에는 여러 가지 상황이 있습니다. 예를 들어,이 상황은 :

http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx

그러나, 안전하고, 잘 동작하는 C# 프로그램이 구현 정의 동작을 가지고있는 경우는 매우 드문해야한다.

+0

아, 과부하 문제는 정말 이상합니다. 그리고 DivisionByZeroException은'1/0'의 예상 된 동작이라고 생각했습니다. 어쨌든, 내일 +1 할거야 ... –

+1

누가 0으로 나눈 값에 대해 말한거야? –

+4

@ Eric : 당신이 언급 한 코너 케이스가 보통 1/0이라고 생각했습니다. 나는 주변을 수색했고 실제로'int.MinValue/-1'라는 것을 발견했다. –

13

위키를 살펴보면 정의되지 않은 동작이 발생하는 상황이 허용되지 않거나 C#에서 예외가 발생합니다. 그건 당신이 포인터 등을 사용할 수 있습니다으로 안전하지 않은 코드 그러나

은, 내가 믿는 정의되지 않은 동작이 가능하다

편집 : 보입니다 내가 옳다 같은 : http://msdn.microsoft.com/en-us/library/aa664771%28VS.71%29.aspx

이 정의되지 않은 동작의 예를 가지고 in C#

+6

당신이 "위키"라고 말하면 어떤 위키를 언급하고 있습니까? –

+0

예, 안전하지 않은 코드를 사용하면 정의되지 않은 동작이 발생할 수 있습니다. +1 –

+1

@Jeff Yates : 질문에서 "정의되지 않은 동작"링크가 위키피디아로 연결됩니다. – Powerlord

-1

정확하게 Wiki 감각은 아니지만 마음에 떠오르는 가장 확실한 예제는 단순히 스레드 코드를 작성하는 것 뿐이지 만 모든 언어에서 그와 비슷합니다.

+3

그건 비 결정적이지, 정의되지 않은 것입니다. 각 스레드가 수행 할 작업을 정확히 보장합니다. 일이 일어난 정확한 순서를 알지 못하기 때문에 놀라운 결과를 얻을 수 있습니다. – jalf

+2

@mfloryan : 불행히도, C#에서 새 스레드를 생성 할 때마다 NetHack 게임을 시작할 수는 없습니다. 아, 좋은 시간에 gcc를 실행하여 재생할 수 있습니다. –

0

일반적으로 나는 아니오라고 대답합니다.

자동 변수를 초기화하기 전에 사용하십시오.

모든 변수를 초기화해야합니다. 그렇지 않으면 예외가 발생합니다. 제로

예외로

사업부가 발생합니다.

Aequitarum Custos 당신이 안전하지 않은 코드를 사용할 수 있습니다 지적

예외가

을 발생합니다 범위에서 배열을 인덱싱. 그렇다면 다시 C#이 아닙니다. C# 환경을 명시 적으로 거부하고 있습니다.

+2

안전하지 않은 코드는 * C *입니다. 귀하가 거부하는 것은 관리 코드의 보증입니다. –

+0

이것은 안전하지 않습니다 * C# 안전하지 않습니다 { int * px1; int * px2 = & i; F (out px1, ref px2); Console.WriteLine ("* px1 = {0}, * px2 = {1}", * px1, * px2); // 정의되지 않은 동작 } 예 C#으로 작성되었습니다. –

+5

물론 이건 완전히 합법적 인 C#입니다. 선택적 "안전하지 않은"하위 집합을 구현하는 C# 구현은 여전히 ​​C#의 구현입니다. –

11

ECMA-334 문서 (p.473) :

정의되지 않은 동작이 발생할 수없는 안전하지 않은 수정 의 발생을 포함하지 않는 프로그램입니다.

Eric Lippert의 답변을 보면 최악의 경우에 '구현 정의'가 가능합니다.

+0

최소한 C 스펙에서 용어가 사용됨에 따라 구현 정의보다는 지정되지 않음.스펙이 구현을 Implementation-Defined로 간주하는 경우, 준수 구현은 프로그래머가 정확히 어떻게 동작 하는지를 알 수있는 충분한 문서를 제공해야합니다. 구현은 합법적으로 달의 각 상반기 동안 -126을, 그리고 후반 동안 -127을 산출 할 수 있다고 정당화 할 수 있지만 실제로 구현이 달의 위상을 확인하는 경우에만 합법적으로 지정할 수 있습니다. 구현은 단순히 "임의의 값을 산출"한다고 말할 수 없습니다. – supercat

23

예! 안전한 상황에서도 그렇습니다! (음, 구현이 정의되지 않았 음을 정의했습니다.)

Roslyn issues에있는 Marek Safar와 VSadov가 있습니다. bool과 관련하여 C#과 CLI가 일치하지 않습니다.

C#은 true의 한 종류와 false의 한 종류 만 있다고 생각합니다.

CLI는 false이 0을 포함하는 바이트이고 다른 모든 값은 true이라고 생각합니다.

이 차이는 우리가해야 할 C 번호를 강제 수 있음을 의미 일부 A (가장자리) 흥미로운 일 :

//non-standard bool 
//We're setting a bool's value to a byte value of 5. 
var a = new bool[1]; 
Buffer.SetByte(a, 0, 5); 

//non-standard bool 
//We're setting a bool's value to a byte value of 10. 
var b = new bool[1]; 
Buffer.SetByte(b, 0, 10); 

//Both are true. 
Console.WriteLine(a[0]); 
Console.WriteLine(b[0]); 

//But they are not the same true. 
Console.WriteLine(a[0] == b[0]); 

위의 출력 :

true

true

,

흥미롭게도, 디버거 동의하지는 (다른 진실을 평가해야합니다?)

enter image description here

어쨌든

에서 C# 팀이 나타나는 결론은 (강조는 추가)되어 온 것으로 :

IE 언어는 비표준 bool에 전혀 관심이 없습니다. (CIL에 MS C#에서와 같은) 특정 구현은 비표준 bools의 존재를 인정하고 정의되지 않은

+2

이것은 실제로 나를 크게 웃게했다. –

1

많은 및 서브 프로그램으로 요약 할 수 있습니다 요구 사항을 가지고 자신의 동작을 지정합니다

  1. 을 유효한 데이터가 주어지면 유효한 출력을 생성합니다.

  2. 잘못된 입력을 받았을 때라도 핵 미사일 발사 또는 시간 및 인과 관계의 법칙 위반을 자제합니다.

Java 및.NET 언어는 코드가 "안전하지 않은"것으로 표시된 특정 코드를 사용하지 않으면 위의 두 번째 제약 조건을 충족시키기 위해 특별한 노력이 필요하지 않습니다. [가비지 수집 및 Finalize과 관련된 일부 동작은 시간/인과 관계에서 약간 이상 할 수 있습니다 관점에서 볼 때, 그것들은 완전한 인과 관계가 아닌 인과 관계의 일반적인 규칙에 대한 예외로 기술 될 수있다. 이러한 상황은 많은 종류의 데이터 의존적 오류 (예 : 정수 오버플로)로 인해 오버플로를 방지하는 데 필요한 가정을 포함하여 컴파일러가 임의의 방식으로 작동 할 수있는 C의 상황과 매우 다릅니다. 하이퍼 모던 C 철학에서 권장되는 진실로 끔찍한 종류의 정의되지 않은 행동은 C# 또는 "안전하지 않은"블록 외부의 다른 .NET 언어에는 존재하지 않습니다.