2009-04-15 2 views

답변

14

필드는 유형의 논리 0으로 자동 초기화됩니다. 이것은 함축적이다. 변수는 "명확한 할당"을 따라야하므로 이 할당되기 전에 할당되어야합니다.

ECMA의 334v4

§17.4.4 필드 초기화

가 고정 필드 또는 인스턴스 이 필드 여부 필드의 초기 값은 디폴트 값 (§12.2) 필드의 유형은 입니다. 앞에이 필드의 값을 관찰 할 수 없으므로이 기본 초기화에 이 발생했으며 필드는 결코 "초기화되지 않음"입니다.

§12

. 변수

... 값을 얻기 전에 변수가 지정되어야합니다 (§12.3). ...

+0

. 하지만 왜? –

+0

@YairHalberstadt는 "이유"에 따라 달라집니다. 하나는 규칙 또는 규칙 뒤에있는 이유를 의미합니다. 나는 첫 번째 질문에 답했다. 두 번째로 : 당신이 생성자 체인을 고려할 때, 가상 메소드가 호출되는 동안 호출되고, IL 레벨의 기본 생성자가 호출 체인의 어느 시점에서든 호출 될 수 있다는 사실 때문에 - 아무 것도 말하기가 거의 불가능 해집니다. 필드 초기화에 대해 합리적인; 똑같이 필드가 겹쳐져 공간을 제로로 만드는 것이 더 중요하므로 아무런 초기화도 기술적으로 필요하지 않습니다. - contrast ... –

+0

@YairHalberstadt 아주 쉬운 할당 검사가있는 로컬 변수는 초기화되지 않은 것이 보통 오류를 의미하며 여기서 우리는 (현재 런타임이 결코 수행하지 않더라도, IIRC) 제로를 건너 뛸 수 있습니다. –

4

실제로는 안됩니다. 오류는 첫 번째가 아니라 두 번째 줄에 있어야하며 초기화하기 전에 사용했기 때문에 오류가 발생해야합니다.

여기에서 컴파일러가 도움을줍니다.

그래서 습관으로 초기화하지 말고 대신 컴파일러에서 도와주세요!

이것에 대한 좋은 점은 경로 확인을 할 것입니다. 각각의 값을 설정하는 3 가지 경우가 있지만 "기본값"으로 설정하는 것을 잊지 만 이후에 사용하면 스위치가 경로를 놓쳤다 고 경고합니다.

변수를 = 0으로 초기화하면 그 이점을 활용할 수 있습니다.

+0

초기화하기 전에 test1도 사용했지만 괜찮 았습니다. –

+0

예, 동일한 검사는 클래스 변수에 도움이되지 않습니다 - 경로를 추적 할 수있는 방법이 없습니다. 최종 경로를 만들지 않으면 경로가 확정됩니다. 생성자에 채워짐 (가능하면 좋은 생각) –

+0

경로 검사가 너무 화려하지는 않지만. 예 : 그런 말을 해봅시다.'bool a, b = true; if (b) a = 참; 부울 c = a;'. ********************************************************************************************************************************** 컴파일러는 조건이 너무 단순하고 항상 사실 일 때도 내부를 보지 않습니다. (그래서 더 복잡한 경우에도 적용됩니다.) – Sushi271

2

마크 (Marc)가 말했듯이 사양에서 말하는 것입니다. 이것이 좋은 일인 이유는 지역 변수가 아닌 초기화되지 않은 멤버를 유지하는 몇 가지 유효한 이유가 있다는 것입니다. 멤버의 수명은 해당 메소드에 의해 제한됩니다. 대부분 성능상의 이유로 인해이 옵션을 원합니다. 변수는 초기화하는 데 비용이 많이 들고 특정 사용 시나리오에서만 초기화해야합니다. 내 부분을 위해, 나는 등을 진정으로 벽에 반대하는 때까지, 초기화되지 않은 회원을 피할거야!

로컬 변수의 경우 모든 코드 경로가 초기화로 이어질 가능성이 있는지 여부를 감지하는 것이 훨씬 쉽지만 전체 프로그램의 모든 코드 경로가 사용하기 전에 초기화를 보장하는지 여부를 결정하는 좋은 방법은 없습니다. 모든 CS 학생들이 알아야 할 정확한 대답은 impossible in both cases입니다.

12

로컬 변수 초기화는 확인 과정과 관련이 있습니다.
CLI는 확인 가능한 코드 (SecurityPermission 속성의 SkipVerfication 속성을 사용하여 확인 프로세스를 건너 뛰도록 명시 적으로 요청하지 않은 모듈)에서 모든 로컬 변수를 사용하기 전에 초기화해야합니다. 그렇게하지 않으면 VerficationException이 발생합니다.

더 흥미롭게도 컴파일러는 로컬 변수를 사용하는 모든 메서드에 .locals init 플래그를 자동으로 추가합니다. 이 플래그는 JIT 컴파일러가 모든 로컬 변수를 기본값으로 초기화하는 코드를 생성하도록합니다. 즉, 자신의 코드에서 이미 초기화 한 경우에도 JIT는 .locals init 플래그를 준수하고 적절한 초기화 코드를 생성합니다. 이 "중복 초기화"는 최적화를 허용하는 구성에서 JIT 컴파일러가 복제를 감지하여 효과적으로 "데드 코드"로 처리하므로 성능에 영향을 미치지 않습니다 (자동 생성 된 초기화 루틴은 생성 된 어셈블러 명령어에 나타나지 않습니다).

대부분의 경우 프로그래머가 로컬 변수를 초기화하지 않을 때 마이크로 소프트 (또한 그의 블로그에 대한 질문에 대한 답변에서 Eric Lippert에 의해 백업 됨)에 따르면 프로그래머는 자신의 로컬 변수를 초기화하지 않을 때 기본 환경으로 변수를 초기화하는 것이 기본 환경이지만 "잊어 버린"경우에만 수행되므로 때로는 환상적인 논리적 버그가 발생합니다.
그래서 C# 코드에서 이러한 특성의 버그 가능성을 줄이기 위해 컴파일러는 여전히 로컬 변수를 초기화 할 것을 주장합니다. 생성 된 IL 코드에 .locals init 플래그를 추가 할 예정이지만 이 주제에

보다 포괄적 인 설명은 여기에서 찾을 수 있습니다 : 단지 질문을 반복하는 것 그 Behind The .locals init Flag

관련 문제