বাতিল, অবসান বা প্রস্থান?


112

এই তিনটির মধ্যে পার্থক্য কী, এবং আমি ব্যতিক্রমের ক্ষেত্রে প্রোগ্রামটি কীভাবে শেষ করব যা আমি সঠিকভাবে পরিচালনা করতে পারি না?


3
এটি কোনও সদৃশ নয়, বরং কিছু ভাল উত্তরের সাথে একটি উপসেট স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 397075/… এবং এটি সি ++ তেও ট্যাগ ছিল!
এলি ক্যাসেলম্যান

std::abortযদি কোনও ব্যতিক্রম কোনও ডেস্ট্রাক্টরকে সমাধান করা না যায় তবে যুক্তিসঙ্গত।
ড্যানিয়েল

1
জন্য আরও তথ্য সম্পর্কে std::terminateAndrzej এর চমৎকার সি এই নিবন্ধ দেখুন ++, ব্লগ: akrzemi1.wordpress.com/2011/09/28/who-calls-stdterminate , akrzemi1.wordpress.com/2011/10/05/using-stdterminate
ওহদ স্নাইডার

উত্তর:


3

আমার পরামর্শ হবে তাদের কোনও ব্যবহার না করা। পরিবর্তে, catchব্যতিক্রমগুলি আপনি পরিচালনা করতে পারবেন না main()এবং returnসেখান থেকে কেবল । এর অর্থ হল যে আপনি গ্যারান্টিযুক্ত যে স্ট্যাক আনওয়াইন্ডিং সঠিকভাবে ঘটে এবং সমস্ত ধ্বংসকারীদের ডাকা হয়। অন্য কথায়:

int main() {
    try {
       // your stuff
    }
    catch( ... ) {
       return 1;    // or whatever
    }
}

8
@ নীল: মূলত সম্মত, তবে প্রোগ্রামটি পরিচালনা করতে পারে না এমন ব্যতিক্রমগুলি রিপোর্ট করা উচিত এবং পুনর্বিবেচনা করা উচিত। অ্যাপটি ক্রাশ হতে দিন।
জন ডিবলিং 12'10

13
স্ট্যাকটি অনাবৃত হয় তা নিশ্চিত করার জন্য আপনার সর্বদা প্রধান হওয়া উচিত। তবে আমি ক্যাচ থেকে আবার ছুঁড়ে ফেলতাম। কিছু ডি ওএসের ডিবাগ-ইন-অবকাঠামো স্বয়ংক্রিয়ভাবে চালনার ক্ষমতা থাকলে আপনি ডিবাগ-এ সংকলন করেছেন।
মার্টিন ইয়র্ক

5
এমনকি একটি শীর্ষ স্তরের হ্যান্ডলার দ্বারা ধরা পড়েনি এমন ব্যতিক্রমগুলি সিস্টেম রিপোর্টিংয়ের সুবিধা প্রেরণ করতে পারে যা প্রক্রিয়াটি হ্রাস করে এবং উইন্ডোজ ত্রুটি প্রতিবেদন, ম্যাক ওএস এক্স ত্রুটি প্রতিবেদন এবং আইফোন অ্যাপ্লিকেশন ত্রুটির লগগুলির মতো বিকাশকারীদের দৃষ্টি আকর্ষণ করার জন্য ব্যতিক্রম প্রতিবেদনটি আপলোড করে।
JBRWilkinson

6
@ জন আমার কাছে অবাক হওয়ার কারণটি হ'ল যদিও এটি ব্যতিক্রমগুলি কীভাবে বাস্তবে প্রয়োগ করা হয় তার আলোকে সঠিক ধারণা দেয়, তবে কোনও উপযুক্ত হ্যান্ডলার সন্ধান না হওয়া অবধি একটি ব্যতিক্রম "স্ট্যাকটি প্রচার করে" ব্যর্থ করে দেয় (বা সমাপ্ত হয় বলা হয়)। এবং ফাঁস বিমূর্ততা, প্রায়শই অনিবার্য, যখন মুখোমুখি হয় তখন অগত্যা অবাক করে তোলে।
টাইলার ম্যাকহেনরী

11
-1 কারণ এটি অর্ধেক প্রশ্নের উত্তর দেয় না। "[অবান্তর, সমাপ্ত বা প্রস্থান করার মধ্যে পার্থক্য কী?]" "এটি আরও ভাল উত্তর: stackoverflow.com/a/397081/353094 এছাড়াও স্ট্যাকওভারফ্লো.com/ a/ 2820407/353094 একটি দুর্দান্ত উত্তর।
leetNightshade

149
  • অ্যাওর্ট প্রোগ্রামটির "অস্বাভাবিক" প্রান্তকে নির্দেশ করে এবং পসিক্স সিগন্যাল সিগাবিআরটি উত্থাপন করে যার অর্থ আপনি যে সিগন্যালের জন্য নিবন্ধভুক্ত করেছেন যে কোনও হ্যান্ডলারের আবেদন করা হবে, যদিও প্রোগ্রামটি উভয় ক্ষেত্রেই আফটারওয়ার্ড বন্ধ করে দেবে। সাধারণত আপনি abortএকটি সি প্রোগ্রামে কোনও অপ্রত্যাশিত ত্রুটি কেস থেকে বেরিয়ে আসার জন্য ব্যবহার করবেন যেখানে ত্রুটিটি খারাপ ইনপুট বা নেটওয়ার্ক ব্যর্থতার মতো কিছু না করে প্রোগ্রামে বাগ হতে পারে। উদাহরণস্বরূপ, আপনি abortযদি কোনও ডেটা স্ট্রাকচারের মধ্যে কোনও নুল পয়েন্টার পাওয়া যায় তবে যখন এটি যুক্তিযুক্তভাবে কখনও না ঘটে।

  • প্রস্থানটি প্রোগ্রামের একটি "স্বাভাবিক" প্রান্ত নির্দেশ করে, যদিও এটি এখনও ব্যর্থতা নির্দেশ করতে পারে (তবে কোনও বাগ নয়)। অন্য কথায়, আপনি exitযদি ত্রুটি কোড সহ ব্যবহার করতে পারেন যদি ব্যবহারকারী ইনপুট দেয় যা পার্স করা যায় না, বা কোনও ফাইল পড়তে না পারে। 0 এর একটি প্রস্থান কোড সাফল্যের ইঙ্গিত দেয়। exitপ্রোগ্রামটি শেষ হওয়ার আগে হ্যান্ডলারদের কল করে। এগুলি atexitএবং on_exitফাংশনগুলির সাথে নিবন্ধিত রয়েছে ।

  • স্ট্যান্ড :: সমাপ্তি হ'ল সি -++ প্রোগ্রামে স্বয়ংক্রিয়ভাবে ডাকা হয় যখন কোনও অপ্রয়োজনীয় ব্যতিক্রম থাকে। এটি মূলত সি ++ এর সমতুল্য abort, ধরে নিই যে আপনি ব্যতিক্রম ছোঁড়ার মাধ্যমে আপনার সমস্ত ব্যতিক্রমী ত্রুটিগুলি রিপোর্ট করছেন। এটি এমন একটি হ্যান্ডলারকে কল করে যা std::set_terminateফাংশন দ্বারা সেট করা হয় , যা ডিফল্টরূপে কেবল কল করে abort

সি ++ এ আপনি সাধারণত কলিং abortবা exitত্রুটি থেকে বাঁচতে চান , যেহেতু আপনি কোনও ব্যতিক্রম ছুঁড়ে ফেলা এবং কোড স্ট্যাকটি আরও বাড়িয়ে দিয়ে প্রোগ্রামটি শেষ করা উপযুক্ত কিনা তা স্থির করে নেওয়া ভাল। আপনি exitসাফল্যের জন্য ব্যবহার করেন বা না করেন তা পরিস্থিতি সম্পর্কিত বিষয় - এটির রিটার্নের বিবৃতি ব্যতীত অন্য কোথাও প্রোগ্রামটি শেষ করা বুদ্ধিমান কিনা main

std::terminateএমনকি সি ++ তেও একটি সর্বশেষ-ডাচ ত্রুটির প্রতিবেদন করার সরঞ্জাম হিসাবে বিবেচনা করা উচিত। সঙ্গে সমস্যা std::terminateযে বিনষ্ট হ্যান্ডলার হয় না ব্যতিক্রম যে Unhandled গিয়েছিলাম এক্সেস আছে, তাই কোন উপায় বলতে এটা কি ছিল না। আপনি সাধারণত কোনও try { } catch (std::exception& ex) { }ব্লকের মূল পুরোটা মুড়ে ফেলার চেয়ে আরও ভাল । অন্ততপক্ষে আপনি প্রাপ্ত ব্যতিক্রমগুলি সম্পর্কে আরও তথ্যের প্রতিবেদন করতে পারেন std::exception(যদিও ব্যতিক্রমগুলি যেগুলি থেকে উদ্ভূত হয়নি std::exceptionএখনও অবিকৃতভাবেই শেষ হবে না)।

লাশ মোড়ানো mainমধ্যে try { } catch(...) { }অনেকটা হ্যান্ডলার বিনষ্ট, কারণ আবার আপনাকে প্রশ্নে ব্যতিক্রম প্রবেশাধিকার নেই সেটিং বেশী ভালো নয়। সম্পাদনা করুন: নীল বাটারওয়ার্থের উত্তর অনুসারে, এই ক্ষেত্রে স্ট্যাকটি অযাচিত যে কোনও সুবিধা রয়েছে যা একটি নিয়ন্ত্রণহীন ব্যতিক্রমের জন্য (কিছুটা আশ্চর্যজনকভাবে) সত্য নয়।


10
আপনি এই উত্তরটি C ++ 11 তথ্যের সাথে আপডেট করতে পারবেন? দেখে মনে হচ্ছে ক্যাচ (...) এবং টার্মিনেট হ্যান্ডলারের ক্ষেত্রে এখন ব্যতিক্রম পাওয়ার উপায় রয়েছে।
ক্লাইম

1
C ++ বিনষ্ট হ্যান্ডলার করে মাধ্যমে ব্যতিক্রম এক্সেস আছে std::current_exception()। উদাহরণটি এখানে দেখুন: akrzemi1.wordpress.com/2011/10/05/ using
anorm

আপনি বর্তমান ব্যতিক্রম পেতে পারেন তা বিবেচ্য নয়, যেহেতু আপনি এটি পরিদর্শন করতে পারবেন না। আপনি যা করতে পারেন তা এটিকে আবার ফেলে দেওয়া throw
seattlecpp

2
@ স্যাটেলিকপ্প আপনি এটিকে পুনর্বিবেচনা করতে পারেন এবং এটির একটি রেফারেন্স ধরতে পারেন, যা আপনি তখন পরিদর্শন করতে পারেন
gpeche

16

std :: abort and std :: প্রস্থান (এবং আরও: std :: _ প্রস্থান, std :: quick_exit) কেবলমাত্র নিম্ন স্তরের ফাংশন। আপনি প্রোগ্রামটি ঠিক কী করতে চান তা জানানোর জন্য এগুলি ব্যবহার করেন: কোন ডেস্ট্রাস্টার (এবং যদি) কল করতে হবে, অন্য কোন ক্লিন-আপ ফাংশনগুলি কল করতে হবে, কোন মানটি ফিরে আসবে ইত্যাদি

std :: টার্মিনেটটি একটি উচ্চ স্তরের বিমূর্ততা: প্রোগ্রামটিতে কোনও ত্রুটি ঘটেছে এবং এটি কোনও কারণে ব্যতিক্রম ছুঁড়ে দিয়ে পরিচালনা করা সম্ভব নয় তা নির্দেশ করার জন্য এটি (রান-টাইম বা আপনি উভয় দ্বারা) বলা হয়। ব্যতিক্রমী প্রক্রিয়াতে নিজেই ত্রুটি দেখা দিলে সাধারণত এর প্রয়োজনীয়তা দেখা দেয় তবে আপনি যখনই আপনার প্রোগ্রামটি প্রদত্ত ত্রুটিটি অতিক্রম করতে চান না তখন আপনি এটি ব্যবহার করতে পারেন। যখন আমার পোস্টে স্ট্যান্ড :: টার্মিনেট আহ্বান করা হয় তখন আমি পরিস্থিতিগুলির সম্পূর্ণ তালিকা সংকলন করি। এটি স্ট্যান্ড :: টার্মিনেট কী করে তা নির্দিষ্ট করা হয়নি কারণ আপনি এটির নিয়ন্ত্রণে রয়েছেন। কোনও ফাংশন নিবন্ধ করে আপনি আচরণটি কনফিগার করতে পারেন। আপনার সীমাবদ্ধতা হ'ল ফাংশনটি ত্রুটি সাইটে ফিরে আসতে পারে না এবং এটি একটি ব্যতিক্রমের মাধ্যমে প্রস্থান করতে পারে না, তবে প্রযুক্তিগতভাবে আপনি এমনকি নিজের বার্তা পাম্পটি ভিতরে শুরু করতে পারেন। আপনি ভিতরে দরকারী জিনিসগুলির তালিকার জন্য, আমার অন্যান্য পোস্টটি দেখুন

বিশেষত নোট করুন যে স্ট্যান্ড :: টার্মিনেটকে প্রসঙ্গে একটি ব্যতিক্রম হ্যান্ডলার হিসাবে বিবেচনা করা হয় যেখানে স্ট্যান্ড :: টার্মিনেটকে হ্যান্ডেল করা যায় না এমন একটি নিক্ষিপ্ত ব্যতিক্রমের কারণে ডাকা হয় এবং আপনি ব্যতিক্রমটি কী তা যাচাই করতে পারেন এবং সি ++ ব্যবহার করে এটি পরিদর্শন করতে পারবেন ১১ টি স্ট্যান্ড :: রিথ্রো এক্সসেপশন এবং স্ট্যান্ড :: কারেন্ট_ এক্সসেপশন ব্যবহার করে। এটা আমার পোস্টে সব ।


সিস্টেম সিগন্যালের কারণে প্রোগ্রামটি বন্ধ হয়ে যাওয়ার ক্ষেত্রে কী ক্লিনআপ হ্যান্ডলার রাখার পরামর্শ দেওয়া হচ্ছে? উদাহরণস্বরূপ, অবৈধ মেমরির অ্যাক্সেস SIGSEGV সংকেত উত্পন্ন করে। এই ক্ষেত্রে, প্রোগ্রামটি শেষ হয়ে যাওয়ার এবং কোর ফাইলটি রাখা বা ক্লিনআপটি করার জন্য একটি সিগন্যাল হ্যান্ডলারের নিবন্ধন করা ভাল কি ?? স্ট্যান্ড :: টার্মিনেট পরিচালনা করার সময় ক্লিনআপ করার তুলনায় সিস্টেম সিগন্যালগুলি পরিচালনা করার সময় কি ক্লিনআপ করার কোনও উদ্বেগ রয়েছে?
কার্তিক ত্রিভিক্রম

12

quick_exit () !

যদি আপনার প্রোগ্রামটি বহু-থ্রেডযুক্ত হয়, তবে কলিংয়ের exit()ফলে সম্ভবত ক্রাশ ঘটতে পারে কারণ গ্লোবাল / স্ট্যাটিক std::threadঅবজেক্টগুলি তাদের থ্রেড ছাড়াই বিনষ্ট করার চেষ্টা করা হবে।

আপনি যদি কোনও ত্রুটি কোডটি ফিরে আসতে চান এবং প্রোগ্রামটি (সাধারণত কম বা বেশি) প্রস্থান করতে চান তবে quick_exit()মাল্টি-থ্রেডেড প্রোগ্রামগুলিতে কল করুন । অস্বাভাবিক সমাপ্তির জন্য (ত্রুটি কোড নির্দিষ্ট করার কোনও সম্ভাবনা ছাড়াই), abort()বা কল করা std::terminate()যেতে পারে।

দ্রষ্টব্য: কুইক_এক্সিট () এমএসভিসি ++ দ্বারা সংস্করণ 2015 পর্যন্ত সমর্থিত নয়


4
  • সমাপ্তি আপনাকে যখন ডাকা হবে তখন কী হবে তা নিবন্ধ করার সম্ভাবনা ছেড়ে দেয়। অন্য দুজনের একজন হওয়া উচিত।
  • প্রস্থানটি একটি প্রস্থান স্থিতি নির্দিষ্ট করার অনুমতি দেয় এমন একটি সাধারণ প্রস্থান। At_exit () দ্বারা নিবন্ধিত হ্যান্ডলারগুলি চালিত হয়
  • গর্ভপাত একটি অস্বাভাবিক প্রস্থান হয়। কেবলমাত্র যা চালানো হয় তা হ'ল SIGABRT এর জন্য সিগন্যাল হ্যান্ডলার।

4
  • সমাপ্তি () স্বয়ংক্রিয়ভাবে কল করা হয় যখন কোনও ব্যতিক্রম ঘটে যা পরিচালনা করা যায় না। ডিফল্টরূপে, সমাপ্তি () কলটি বাতিল () করে। আপনি set_terminate () ফাংশন সহ একটি কাস্টম হ্যান্ডেল সেট করতে পারেন।

    abort () SIGABRT সিগন্যাল প্রেরণ করে।

    প্রস্থান () অগত্যা কোনও খারাপ জিনিস নয়। এটি সফলভাবে অ্যাপ্লিকেশনটি প্রস্থান করে এবং লিফোর ক্রমে অ্যাক্সিট () ফাংশনগুলিকে কল করে। আমি সাধারণত এটি সি ++ অ্যাপ্লিকেশনগুলিতে দেখতে পাই না তবে আমি এটি অনেকগুলি ইউনিক্স ভিত্তিক অ্যাপ্লিকেশনগুলিতে দেখতে পাই যেখানে এটি শেষে একটি প্রস্থান কোড প্রেরণ করে। সাধারণত একটি প্রস্থান (0) অ্যাপ্লিকেশনটির সফল রান নির্দেশ করে।


8
ব্যার্থ! ইউনিক্স এবং ডস উভয় ক্ষেত্রে, প্রস্থান (0) সাফল্যের ইঙ্গিত দেয় এবং প্রস্থান করার জন্য পাস করা অন্য কোনও মান () ব্যর্থতা নির্দেশ করে, অন্যভাবে নয়!
রিচার্ড ব্যারেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.