2016-07-19 6 views
3

저는 PascalScript innosetup 설치 프로그램을 사용하고 있는데, 다음 블록의 제어가 어디로 흐르고 있는지 알지 못합니다.파스칼 (스크립트) 및 예외 제어 흐름

function Foo(): String; 
begin 
    Result := 'foo'; 
    RaiseException('...'); 
end; 

procedure Test(); 
var 
    Z : String; 
begin 
    Z := ''; 
    try 
    Z := Foo(); 
    except 
    Log(Z); 
    end 
end; 

내 설치 ZFoo 함수의 Result으로 설정되는 것처럼 보입니다. '대부분의'프로그래밍 언어의 예외에 대한 나의 이해는 Z := Foo() 예외가 발생하지 않아야한다는 것을 나에게 알려준다.

Foo 함수가 발생하면 Z이 여전히 할당되어야합니까?

+1

@ MartinPrikryl : 네 말이 맞아. 나는 수작업으로 혼합 된 예제와 생산 코드를 사용한다. 나는 그것을 컴파일하고 실행했다. – xtofl

답변

2

아마도 암시 적 첫 번째 인수로 참조로 결과 값을 처리합니다. 하지만 그런 일이 일어날 수 있습니다. 반환 값을 처리하는 일반적인 방법이기 때문에 특정 코드 생성/최적화의 법칙으로 간주 될 수 있습니다.

그러나 오브젝트 파스칼에서 델파이가 수행하는 테스트가 정확히 정의되지 않은 이유는 어두운 영역이므로 x86 및 x86_64 구현 만 있기 때문입니다. 그리고 델파이는 eax에서 값을 반환 할 것이므로 만약 당신이 그 논리를 따른다면 이것은 불법입니다.

내가 구조화 유형 델파이를 테스트하고,이 기준을 통과하면서, 그것을 통과하는 스택의 복사본을 생성한다

나중에 첨가.

이렇게하면 구조화 된 유형으로 코드를 최적화하는 것이 어려울 수 있지만 반환 유형 const를 선언하는 수정 자/속성이 필요하다면이를 수정할 수 있습니다.

+1

필자는 Delphi를 구조화 된 형식으로 테스트했으며 참조를 전달하는 동안 스택에 복사본을 만들어 전달합니다. 그래서 그게 버그가됩니다. 비록 델파이가 참고로 전달하더라도 그러한 경우에 대비합니다. (성능의 비용으로) –

+0

"스택에 복사"는 무슨 뜻입니까? 여기에 "버그"가 무엇입니까? –

+0

파스칼 스크립트의 버그. 복잡한/구조화 된 반환 값의 경우 FPC와 Delphi는 반환 유형과 동일한 유형의 임시 변수를 만든 다음 참조로 전달합니다. 함수를 호출 한 후 결과는 최종 목적지로 복사됩니다. 전체 목적지는 PascalScript –

2

델파이에서 결과 값 문자열은 var 매개 변수와 같이 처리됩니다.

procedure Foo(var Result: string); 
begin 
    Result := 'Foo'; 
    RaiseException(...); 
end; 

Z (기준 파라미터를 통해)이 즉시 값 'Foo' 할당 즉 전에 예외가 발생한다는 의미로 말해서, 푸 같은 함수는 실제로 컴파일된다.

즉, 함수 결과는 Result이라는 로컬 변수에 보관되지 않고 함수가 끝날 때 반환됩니다. 예외로 인해 방지 될 수 있습니다. 즉, 즉시 할당됩니다.

나는 PascalScript에서도 이러한 현상이 일어나고 있다고 가정합니다.

+0

그래서이 함수는 반환 값에 무슨 일이 일어나는지 알고 있습니다. 그렇다면 함수 호출은'A : = Foo()'와'A : = '... + Foo()'를 어떻게 구별합니까? – xtofl

+0

@xtofl :' '...'+ Foo()'때문에 접근 할 수없는 중간 문자열에 쓰기 때문에. 중간 문자열이''Foo ''로 설정되어 있다고 확신하지만, 예외는 완전한 표현의 형성을 방해합니다. IOW, 중간 : = Foo(); 뒤에'A : = '...'+ 중간; 'intermediate'는 예외 이전에''Foo ''로 설정되지만, 예외가 있기 때문에 전체 표현식은 계속 형성 될 수 없습니다. 그리고 '중간'은 도달 할 수 없습니다. 즉, 코드에서 명시 적으로 참조되지 않습니다. –

+0

그러므로'A : = Foo()'의 경우에는 중간 문자열이 없습니다. 최적화입니까 아니면 언어로 정의되어 있습니까? – xtofl