अभिव्यक्तियों का मूल्यांकन क्रम आमतौर पर अपरिभाषित है। (सी और सी ++ वैसे ही हैं। जावा हमेशा बाएं से दाएं का मूल्यांकन करता है।) कंपाइलर इस पर कोई नियंत्रण नहीं देता है। यदि आपको किसी विशिष्ट क्रम में मूल्यांकन के लिए दो अभिव्यक्तियों की आवश्यकता है, तो अपना कोड अलग-अलग लिखें। मैं वास्तव में कोड की लाइनों की संख्या के बारे में चिंता नहीं करता। रेखाएं सस्ते हैं; जितनी जरूरत हो उतनी उपयोग करें। आप इस पद्धति का उपयोग करते हुए अक्सर पाते हैं, तो एक समारोह है कि यह सभी लपेटता लिख:
function GetFirstIfAvailable(DB: TDatabaseObject; const FieldName: string): Integer;
begin
if DB.First = 0 then
Result := DB.ReturnFieldI(FieldName)
else
Result := 0;
end;
आपका मूल कोड शायद नहीं किया गया है जैसे आप चाहते हैं, भले ही मूल्यांकन के क्रम भिन्न थे। भले ही DB.First
शून्य के बराबर नहीं था, तो ReturnFieldI
पर कॉल का मूल्यांकन अभी भी किया जाएगा। उन सभी कार्यों का उपयोग करने से पहले सभी वास्तविक मानकों का पूरी तरह से मूल्यांकन किया जाता है।
बदलना Math.pas आपको वैसे भी मदद नहीं करेगा। यह नियंत्रित नहीं करता है कि इसके वास्तविक मानकों का मूल्यांकन किस क्रम में किया जाता है। जब तक उन्हें यह देखता है, तब तक उनका पहले से ही एक बूलियन मान और एक पूर्णांक का मूल्यांकन किया जा चुका है; वे अब निष्पादन योग्य अभिव्यक्ति नहीं हैं।
कॉलिंग सम्मेलन मूल्यांकन आदेश को प्रभावित कर सकता है, लेकिन अभी भी कोई गारंटी नहीं है। ऑर्डर जो पैरामीटर को स्टैक पर धक्का दिया जाता है, उस क्रम से मेल खाने की आवश्यकता नहीं होती है जिसमें वे मान निर्धारित किए गए थे।दरअसल, अगर आपको लगता है कि स्टडकॉल या सीडीईएल आपको अपना वांछित मूल्यांकन ऑर्डर (बाएं से दाएं) देता है, तो उनका मूल्यांकन रिवर्स ऑर्डर में किया जा रहा है।
पास्कल कॉलिंग सम्मेलन स्टैक पर बाएं से दाएं तर्क पारित करता है। इसका मतलब है कि बाएंतम तर्क स्टैक के नीचे एक है, और दाएं पते के ठीक नीचे, दाएं दाएं शीर्ष पर है।
जिस तरह से आप उम्मीद करते हैं, जो कि प्रत्येक तर्क का मूल्यांकन किया और तुरंत धकेल दिया जाता है: IfThen
समारोह सम्मेलन बुला का उपयोग किया जाता है, वहाँ कई तरीके संकलक कि ढेर लेआउट प्राप्त कर सकते हैं
push (DB.First = 0)
push DB.ReturnFieldI('awesomedata1')
call IfThen
तर्क मूल्यांकन दाएँ-से-बाएँ और जब तक वे धक्का दिया रहे temporaries में परिणाम की दुकान:
tmp1 := DB.ReturnFieldI('awesomedata1')
tmp2 := (DB.First = 0)
push tmp2
push tmp1
call IfThen
Allo cate ढेर अंतरिक्ष पहले, और में किसी भी क्रम सुविधाजनक है का मूल्यांकन:
sub esp, 8
mov [esp], DB.ReturnFieldI('awesomedata1')
mov [esp + 4], (DB.First = 0)
call IfThen
सूचना है कि IfThen
सभी तीन मामलों में एक ही क्रम में तर्क मान प्राप्त करता है, लेकिन कार्यों जरूरी में कहा जाता है नहीं कर रहे हैं वह आदेश
डिफ़ॉल्ट रजिस्टर कॉलिंग सम्मेलन भी बाएं से दाएं तर्क पास करता है, लेकिन पहले तीन तर्क रजिस्टरों में पास किए जाते हैं। रजिस्ट्रार तर्कों को पारित करने के लिए उपयोग किए जाते हैं, हालांकि, इंटरमीडिएट अभिव्यक्तियों का मूल्यांकन करने के लिए आमतौर पर उपयोग किए जाने वाले रजिस्टरों भी होते हैं। DB.First = 0
का नतीजा ईएक्स रजिस्टर में पारित करने की आवश्यकता है, लेकिन संकलक को ReturnFieldI
पर कॉल करने और First
पर कॉल करने के लिए पंजीकरण करने की भी आवश्यकता है। यह शायद एक छोटे से अधिक इस तरह प्रथम, द्वितीय समारोह का मूल्यांकन करने के लिए सुविधाजनक था:
call DB.ReturnFieldI('awesomedata1')
mov [ebp - 4], eax // store result in temporary
call DB.First
test eax, eax
setz eax
mov edx, [ebp - 4]
call IfThen
का कहना है के लिए एक और बात यह है कि अपने पहले तर्क एक यौगिक अभिव्यक्ति है। एक फ़ंक्शन कॉल और तुलना है। गारंटी देने के लिए कुछ भी नहीं है कि उन दो भागों को लगातार प्रदर्शन किया जाता है। संकलक को First
और ReturnFieldI
पर कॉल करके पहली बार फ़ंक्शन कॉल से बाहर निकल सकता है, और इसके बाद First
शून्य के विरुद्ध वापसी मान की तुलना करें।
यहां तक कि अगर कोई संभावना है - ऐसा मत करो! यदि आपको पहले होने के लिए 'फर्स्ट' कॉल की आवश्यकता है, तो उसे इस तरह कोड करें। इस स्थिति में आईएमएचओ केवल एक स्पष्ट 'if' उचित है। –
मैं आपकी विनम्र राय को ध्यान में रखता हूं, लेकिन क्या आपको नहीं लगता कि IfThen फ़ंक्शन के साथ शुरू करने के लिए पीछे की ओर है? यदि यह अंत में उस वैकल्पिक पैरामीटर के लिए नहीं था, तो यह हमेशा ifThen (TrueResult, FalseResult, BooleanFunction) कहने के लिए और अधिक उपयोगी होगा। आपके तर्क से आप कहेंगे "अगर (functionA और functionB) तो अंत शुरू करें;" हमेशा लिखा जाना चाहिए "अगर फंक्शंस तो फ़ंक्शनब फिर समाप्त होता है;" ? –
जरूरी नहीं है, क्योंकि बूलियन शॉर्टकट मूल्यांकन अच्छी तरह से जाना जाता है जबकि फ़ंक्शन तर्कों का मूल्यांकन आदेश नहीं है। यदि तब आम तौर पर बेकार है क्योंकि यह ** ** ** ** ** ** ** का मूल्यांकन करता है जो मेरे अनुभव में नहीं चाहता था - मैं ज्यादातर ** ** ** सत्य अभिव्यक्ति ** या ** गलत अभिव्यक्ति निष्पादित करना चाहता हूं । –