2017-09-28 59 views
12

को रोकता है पाया कि डेल्फी टोक्यो में अपवाद हैंडलिंग पिछले डेल्फी संस्करणों की तुलना में थोड़ा अलग व्यवहार करता है।डेल्फी टोक्यो अपवाद सेटिंग फ़ंक्शन परिणाम

function FuncTest: integer; 
begin 
    Result := 1; 
    try 
    raise Exception.Create('Error Message'); 
    finally 
    Result := 2; 
    end; 
end; 

function Test:integer; 
begin 
    Result:=0; 
    try 
    Result:=FuncTest; 
    finally 
    ShowMessage(Result.ToString); 
    end; 
end; 

पहले डेल्फी संस्करणों में संदेश बॉक्स "2", टोक्यो - "0" दिखाता है। क्या यह टोक्यो बग है या अपवादों को इस तरह से संभाला नहीं जाना चाहिए?

उत्तर

10

टोक्यो व्यवहार सही है। एक ऐसा कार्य जो अपवाद उठाता है वह एक मूल्य वापस नहीं करता है। अब तक आप कार्यान्वयन विस्तार पर भरोसा कर रहे हैं।

Result:=FuncTest; 

यह इस प्रकार कार्यान्वित:

  1. FuncTest कहा जाता है

    इस कोड पर विचार करें।

  2. Result असाइन किया गया है।

अब, क्योंकि चरण 1 अपवाद उठाता है, चरण 2 निष्पादित नहीं होता है।

यदि कुछ भी है, तो मैं कहूंगा कि पिछले संस्करणों से आप जो व्यवहार रिपोर्ट करते हैं वह संदिग्ध है। इस समारोह में:

function Test:integer; 
begin 
    Result:=0; 
    try 
    Result:=FuncTest; 
    finally 
    ShowMessage(Result.ToString); 
    end; 
end; 

बयान Result:=FuncTest एक अपवाद को जन्म देती है और इतने Result कि बयान से नहीं संशोधित किया जाना चाहिए। इसके बारे में सोचने का एक और तरीका यह है कि फ़ंक्शन को कॉल किया जाता है लेकिन असाइनमेंट निष्पादित नहीं होता है।


डेल्फी ABI साथ समस्या यह है कि समारोह वापसी कभी-कभी मूल्य निहित var मानकों के रूप में लागू कर रहे हैं। जिसका अर्थ है कि असाइनमेंट हो सकता है या नहीं भी हो सकता है। प्रदर्शित करने के लिए:

{$APPTYPE CONSOLE} 

uses 
    System.SysUtils; 

type 
    TRec1 = record 
    X1: NativeInt; 
    end; 

    TRec2 = record 
    X1: NativeInt; 
    X2: NativeInt; 
    end; 

function GetRec1: TRec1; 
begin 
    Result.X1 := 1; 
    raise Exception.Create(''); 
end; 

function GetRec2: TRec2; 
begin 
    Result.X1 := 1; 
    raise Exception.Create(''); 
end; 

procedure Main; 
var 
    Rec1: TRec1; 
    Rec2: TRec2; 
begin 
    Rec1 := Default(TRec1); 
    Writeln(Rec1.X1); 
    try 
    Rec1 := GetRec1; 
    except 
    end; 
    Writeln(Rec1.X1); 

    Rec2 := Default(TRec2); 
    Writeln(Rec2.X1); 
    try 
    Rec2 := GetRec2; 
    except 
    end; 
    Writeln(Rec2.X1); 
end; 

begin 
    Main; 
    Readln; 
end. 

यह आउटपुट:

 
0 
0 
0 
1 

कौन सा नहीं बल्कि निराशाजनक है। कॉलर के चर को संशोधित करना संभव नहीं होना चाहिए, लेकिन मूल्य वापसी के बजाए एक अंतर्निहित var पैरामीटर का उपयोग इस रिसाव की अनुमति देता है। मेरे विचार में यह डेल्फी एबीआई के डिजाइन में एक गंभीर दोष है, यह एक दोष है जिसे आप अन्य भाषाओं में नहीं पाएंगे।


अपने कोड में, वहाँ कोई var पैरामीटर क्योंकि वापसी प्रकार एक रजिस्टर में स्थानांतरित कर रहा है है। 2 आउटपुट करने वाले किसी भी डेल्फी संस्करण को तोड़ दिया गया है।

मूल रूप से, आपका कोड इसकी अपेक्षाओं में गलत है। यदि कोई फ़ंक्शन अपवाद उठाता है तो आपको यह मानना ​​चाहिए कि वापसी मूल्य बीमार है।

अंत में, आपका कोड XE3 और XE7 में 0 आउटपुट करता है, इसलिए मुझे आश्चर्य है कि 2 के मान को देखने के लिए आपको कितनी दूर जाने की आवश्यकता है।

+0

मेरे पास पहले डेल्फी संस्करण नहीं है, लेकिन मुझे लगता है कि यह XE2 है जहां x64 कंपाइलर पेश किया गया था।ए के पास एक कोड है जो इस तथ्य पर निर्भर करता है कि FuncTest या तो 1 (बिना कोशिश ब्लॉक के) देता है या 2. ठीक है, मुझे यह मिला, अपवादों को बढ़ाने के लिए कोई और कार्य नहीं, केवल प्रक्रियाएं। – Molochnik

+1

अपवादों को बढ़ाने के लिए एक फ़ंक्शन के लिए यह ठीक है। उस मामले में मूल्य वापस करने की अपेक्षा करना गलत है। इस मामले में, क्योंकि वापसी का प्रकार किसी रजिस्टर में फिट बैठता है, एबीआई ठीक है, कोई 'var' param मुद्दों नहीं है। लेकिन हाँ, XE2 64 बिट में कुछ अच्छे मुद्दे थे। –

+0

आपका मतलब है कि अगर समारोह ई, जी, एक रिकॉर्ड लौटा तो कोई समस्या नहीं होगी? – Molochnik

संबंधित मुद्दे