आपका S7
पैरामीटर एक out
पैरामीटर के रूप में घोषित किया जाता है, इसलिए जब समारोह कहा जाता है संकलक एक खाली स्ट्रिंग के लिए पारित चर सेट हो जाएगा। आउटपुट पैरामीटर समेत सभी पैरामीटर के लिए आप S
वैरिएबल पास कर रहे हैं, इसलिए S
का मान फ़ंक्शन के अंदर पैरामीटर मानों का उपयोग करने से पहले मेमोरी से मिटा दिया जाता है।
विस्तार करने के लिए आगे, प्रक्रिया register
बुला सम्मेलन, जहां S1
.. S3
(क्रमशः EAX, EDX, और ECX,) CPU रजिस्टरों में पारित कर रहे हैं और S4
.. S6
बजाय ढेर पर पारित कर रहे हैं उपयोग कर रहा है। इनपुट string
चर स्पष्ट वाइप किए जाने से हो रही के बाद अपने वर्तमान मूल्य S4
और S5
के लिए ढेर पर धकेल दिया जाता है (S3
और S6
सिर्फ चर की ओर संकेत करती है), और इससे पहले कि मूल्य S1
और S2
को सौंपा गया है। तो, S1
और S2
अंत तक शून्य, S4
और S5
पोंछ से पहले मूल 'S'
आंकड़ों के संकेत दिए गए होते हैं, और S3
और S6
string
चर कि मिटा दिया गया था पर ओर इशारा करते हैं।
डीबगर आपको यह सब कुछ क्रिया में दिखा सकता है। आप लाइन जहां MyProcedure()
कहा जाता है पर एक ब्रेकपाइंट डाल दिया, और फिर सीपीयू दृश्य खोलें, तो आपको निम्न विधानसभा निर्देश देखेंगे:
StringTest.dpr.17: MyProcedure(S, S, S, S, S, S, S);
00405A6C 8B45FC mov eax,[ebp-$04] // [ebp-$04] is the current value of S
00405A6F 50 push eax // <-- assign S4
00405A70 8B45FC mov eax,[ebp-$04]
00405A73 50 push eax // <-- assign S5
00405A74 8D45FC lea eax,[ebp-$04]
00405A77 50 push eax // <-- assign S6
00405A78 8D45FC lea eax,[ebp-$04]
00405A7B E8B0EDFFFF call @UStrClr // <-- 'out' wipes out S!
00405A80 50 push eax // <-- assign S7
00405A81 8D4DFC lea ecx,[ebp-$04] // <-- assign S3
00405A84 8B55FC mov edx,[ebp-$04] // <-- assign S2
00405A87 8B45FC mov eax,[ebp-$04] // <-- assign S1
00405A8A E8B9FEFFFF call MyProcedure
इसे ठीक करने के लिए, आप एक अलग चर का उपयोग करने के लिए उत्पादन प्राप्त करने की आवश्यकता :
function MyFunction(S1: String; const S2: String; var S3: String;
S4: String; const S5: String; var S6: String): String;
begin
Result := '1' + S1 + '2' + S2 + '3' + S3 + '4' + S4 + '5' + S5 + '6' + S6;
end;
procedure Work;
var
S: String;
begin
S := 'S';
WriteLn(MyFunction(S, S, S, S, S, S));
end;
:
procedure Work;
var
S, Res: String;
begin
S := 'S';
Proc(S, S, S, S, S, S, Res);
WriteLn(Res);
end;
वैकल्पिक रूप से, एक समारोह है कि एक out
पैरामीटर का उपयोग करने का एक नया String
अपने Result
के माध्यम से रिटर्न के बजाय में प्रक्रिया को बदलने
सावधान रहें: जब आप 'const' के साथ पैरामीटर घोषित करते हैं, तो आप संकलक को बता रहे हैं कि उसे उस फ़ंक्शन की अवधि के लिए पैरामीटर को बदलने की अपेक्षा नहीं करनी चाहिए। यह सुनिश्चित करना आपकी ज़िम्मेदारी है कि आप उस वचन को कायम रखें; संकलक इसे आपके लिए जांच नहीं सकता है। इस मामले में, आप 'S7' के माध्यम से' S' संशोधित कर रहे हैं जबकि एक ही समय में 'S2' और' S5' का दावा नहीं होगा। –