সি ++ কোড কিভাবে শেষ করবেন


267

আমি চাইব যে আমার সি ++ কোডটি যদি কোনও শর্ত পূরণ হয় তবে চলমান বন্ধ করুন, তবে আমি কীভাবে এটি করব তা নিশ্চিত নই। সুতরাং ঠিক যে কোনও মুহূর্তে যদি কোনও ifবিবৃতিটি সত্য হয় তবে কোডটি এই জাতীয়ভাবে বন্ধ করুন:

if (x==1)
{
    kill code;
}

98
সঠিক যুক্তি ব্যবহার করুন। ইন main()ব্যবহার রিটার্ন ফাংশন একটি সঠিক ফেরত মান ব্যবহার করুন অথবা একটি সঠিক ব্যতিক্রম নিক্ষেপ করা। ব্যবহার করবেন নাexit() !
কে - এসই খারাপ

6
@ জোনাথনলফলার: NDEBUGসংজ্ঞায়িত সংকলন করার সাথে সাথে assertসম্ভবত একটি অনির্বাণ হয়ে উঠবে, তাই আপনার বাগ সনাক্তকরণের চেয়ে বেশি নির্ভর করার দরকার নেই।
এমভিজি 15'15

13
@ জামেস্কেফ: একটি returnথেকে main()নিখুঁত যৌক্তিক। এটি প্রোগ্রাম দ্বারা প্রতিবেদন করা প্রস্থান কোডটি অপারেটিং সিস্টেমে সেট করে, যা অনেক ক্ষেত্রে কার্যকর হতে পারে (যদি আপনার প্রোগ্রামটি আরও বৃহত প্রক্রিয়ার অংশ হিসাবে ব্যবহার করা যায়, উদাহরণস্বরূপ)।
এএটি

11
মজার বিষয় হল এই প্রশ্নটি 5 বছর আগে থেকে এটির একটি সদৃশ, যার স্বীকৃত উত্তরটি একেবারেই আলাদা: স্ট্যাকওভারফ্লো / প্রশ্নগুলি 11116493 / how- to- quit-ac-pramram আমার ধারণা অনুমান করে যে সম্প্রদায়টি অন্ধভাবে শিখতে 5 বছর সময় নিয়েছে কলিং স্টাডি :: প্রস্থান খারাপ হতে পারে?
ব্র্যান্ডিন 15'15

5
প্রশ্নগুলি কেন ব্যবহারকে exit()খারাপ বলে মনে করা হয়? - এসও 25141737 এবং কীভাবে সি ++ প্রোগ্রাম ছাড়বেন? - এসও 1116493 এখন এটির সদৃশ হিসাবে বন্ধ রয়েছে। এর মধ্যে প্রথমটির কাছে 'ক্র্যাশ-ওনল সফটওয়্যার' এর একটি উল্লেখ রয়েছে যা কেবলমাত্র শক্তিশালী সফ্টওয়্যার কীভাবে লিখতে হয় তা সম্পর্কে আপনার চিন্তাভাবনাকে উত্সাহিত করতে পারলে এটি একবারের জন্য উপযুক্ত।
জোনাথন লেফলার

উত্তর:


431

বেশ কয়েকটি উপায় রয়েছে তবে প্রথমে আপনাকে বুঝতে হবে যে কেন অবজেক্ট ক্লিনআপ গুরুত্বপূর্ণ, এবং তাই কারণটি std::exitসি ++ প্রোগ্রামারদের মধ্যে প্রান্তিক করা হয়েছে।

RAII এবং স্ট্যাক আনওয়াইন্ডিং

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

আপনি যদি ফাইলটি ফ্লাশ এবং বন্ধ করার জন্য ডেস্ট্রাক্টরের কাছে না যান তবে কী হবে? কে জানে! তবে সম্ভবত এটি ফাইলটি লেখার কথা বলেছিল এমন সমস্ত ডেটা লিখবে না।

উদাহরণস্বরূপ এই কোডটি বিবেচনা করুন

#include <fstream>
#include <exception>
#include <memory>

void inner_mad()
{
    throw std::exception();
}

void mad()
{
    auto ptr = std::make_unique<int>();
    inner_mad();
}

int main()
{
    std::ofstream os("file.txt");
    os << "Content!!!";

    int possibility = /* either 1, 2, 3 or 4 */;

    if(possibility == 1)
        return 0;
    else if(possibility == 2)
        throw std::exception();
    else if(possibility == 3)
        mad();
    else if(possibility == 4)
        exit(0);
}

প্রতিটি সম্ভাবনার মধ্যে যা ঘটে তা হ'ল:

  • সম্ভাব্যতা 1: রিটার্নটি মূলত বর্তমান ফাংশনটির সুযোগ ছেড়ে দেয়, সুতরাং এটি osতার ডেস্ট্রাক্টরকে কল করার এবং চূড়ান্তভাবে ফাইলটিকে ডিস্কে ফ্লাশ করে ক্লিনআপ করার মাধ্যমে জীবন চক্রের সমাপ্তির বিষয়ে জানে ।
  • সম্ভাব্যতা 2: একটি ব্যতিক্রম নিক্ষেপ করাও বর্তমান সুযোগে অবজেক্টগুলির জীবনচক্রের যত্ন নেয়, এইভাবে যথাযথ পরিচ্ছন্নতা করা ...
  • সম্ভাব্যতা 3: এখানে স্ট্রাক অযৌক্তিক পদক্ষেপে প্রবেশ করে! যদিও ব্যতিক্রমটি নিক্ষেপ করা হয়েছে inner_mad, আনভিন্ভার চলে যাবে যদিও স্ট্যাক madএবং mainসঠিক পরিচ্ছন্নতা সম্পাদন করার জন্য, সমস্ত বস্তু যথাযথভাবে ধ্বংস হতে চলেছে, সহ ptrএবং সহ os
  • সম্ভাবনা 4: আচ্ছা, এখানে? exitএটি একটি সি ফাংশন এবং এটি সচেতন নয় বা সি ++ আইডিয়ামগুলির সাথে সামঞ্জস্যপূর্ণ নয়। এটি খুব একই স্কোপ সহ আপনার জিনিসগুলিতে পরিষ্কার-পরিচ্ছন্নতা সম্পাদন করে নাos । সুতরাং আপনার ফাইলটি সঠিকভাবে বন্ধ হবে না এবং এই কারণে লিখিত সামগ্রীটি কখনও এতে লিখিত হতে পারে না!
  • অন্যান্য সম্ভাবনাগুলি: এটি একটি মূল return 0কার্য সম্পাদন করে এবং সম্ভাব্য 1 এর সমান প্রভাব রাখায়, যথাযথ পরিচ্ছন্নতার দ্বারা এটি কেবল প্রধান সুযোগ ছাড়বে ।

তবে আমি সবেমাত্র আপনাকে যা বলেছিলাম সে সম্পর্কে এতটা নিশ্চিত হন না (মূলত সম্ভাবনাগুলি 2 এবং 3); পড়া চালিয়ে যান এবং আমরা সঠিক ব্যতিক্রম ভিত্তিক ক্লিনআপ কীভাবে সম্পাদন করব তা খুঁজে বের করব।

শেষ হওয়ার সম্ভাব্য উপায়

মূল থেকে ফিরে!

যখনই সম্ভব আপনার এটি করা উচিত; সর্বদা প্রধান থেকে সঠিক প্রস্থান স্থিতি ফিরে আপনার প্রোগ্রাম থেকে ফিরে আসতে পছন্দ করুন।

আপনার প্রোগ্রামের কলার এবং সম্ভবত অপারেটিং সিস্টেমটি আপনার প্রোগ্রামটি যা করার কথা ছিল তা সফলভাবে হয়েছে কিনা তা জানতে চাইতে পারে। এই একই কারণে আপনি হয় শূন্য ফিরে আসতে হবে বা EXIT_SUCCESSপ্রোগ্রামটি সফলভাবে সমাপ্ত হওয়া এবং EXIT_FAILUREসিগন্যাল করার জন্য যে প্রোগ্রামটি সফলভাবে শেষ হয়েছে এবং সিগন্যাল করার জন্য প্রোগ্রামটি অসফলভাবে শেষ হয়েছে, অন্য কোনও ফিরতি মান রূপায়ণ-সংজ্ঞায়িত ( §18.5 / 8 )।

তবে আপনি কল স্ট্যাকের মধ্যে খুব গভীর হতে পারেন এবং এর সমস্তটি ফিরিয়ে দেওয়া বেদনাদায়ক হতে পারে ...

[করবেন না] একটি ব্যতিক্রম নিক্ষেপ

কোনও ব্যতিক্রম ছুঁড়ে দেওয়া পূর্ববর্তী কোনও সুযোগের প্রতিটি বস্তুর ডেস্ট্রাক্টরকে ডেকে স্ট্যাক আনওয়াইন্ডিং ব্যবহার করে সঠিক অবজেক্ট ক্লিনআপ সম্পাদন করবে।

তবে এখানে ধরা ! এটি প্রয়োগ-সংজ্ঞায়িত করা হয় যখন স্ট্রাকযুক্ত ব্যতিক্রম হ্যান্ডেল করা হয় না তখন ক্যাচ (...) ধারা দ্বারা না করা হয় বা noexceptকল স্ট্যাকের মাঝখানে আপনার কোনও ফাংশন থাকে। এটি .515.5.1 এ বলা হয়েছে [ব্যতীত] শেষ করা :

  1. কিছু পরিস্থিতিতে কম সূক্ষ্ম ত্রুটি পরিচালনার কৌশলগুলির জন্য ব্যতিক্রম হ্যান্ডলিং ত্যাগ করা উচিত। [দ্রষ্টব্য: এই পরিস্থিতিগুলি হ'ল:

    [...]

    - যখন ব্যতিক্রম হ্যান্ডলিং মেকানিজম কোনও ছোঁড়া ব্যতিক্রম (15.3) এর জন্য কোনও হ্যান্ডলারটি খুঁজে না পায় বা যখন কোনও হ্যান্ডলারের সন্ধান (15.3) কোনও noexceptস্পেসিফিকেশন সহ কোনও ফাংশনের বহিরাগত ব্লকের মুখোমুখি হয় যা ব্যতিক্রমটিকে (15.4) অনুমতি দেয় না, বা [...]

    [...]

  2. এই জাতীয় ক্ষেত্রে, স্টাড :: টার্মিনেট () বলা হয় (18.8.3)। যে পরিস্থিতিতে কোনও ম্যাচিং হ্যান্ডলার পাওয়া যায় না, স্ট্যান্ড :: টার্মিনেট () বলা হওয়ার আগে স্ট্যাকটি অযাচিত কিনা তা বাস্তবায়ন-সংজ্ঞায়িত হয় [...]

সুতরাং আমাদের এটি ধরতে হবে!

একটি ব্যতিক্রম নিক্ষেপ এবং এটি মূলত ধরা!

যেহেতু অপ্রকাশিত ব্যতিক্রমগুলি স্ট্যাক আনওয়াইন্ডিং সম্পাদন করতে পারে না (এবং ফলস্বরূপ যথাযথ পরিচ্ছন্নতা সম্পাদন করবে না) , তাই আমাদের ব্যতিক্রমটি মূলত ধরা উচিত এবং তারপরে একটি প্রস্থান স্থিতি ( EXIT_SUCCESSবা EXIT_FAILURE) ফিরিয়ে দেওয়া উচিত ।

সুতরাং সম্ভবত একটি ভাল সেটআপ হবে:

int main()
{
    /* ... */
    try
    {
        // Insert code that will return by throwing a exception.
    }
    catch(const std::exception&)  // Consider using a custom exception type for intentional
    {                             // throws. A good idea might be a `return_exception`.
        return EXIT_FAILURE;
    }
    /* ... */
}

[করবেন না] std :: প্রস্থান করুন

এটি কোনও ধরণের স্ট্যাক অযৌক্তিকভাবে সম্পাদন করে না এবং স্ট্যাকের কোনও জীবন্ত অবজেক্ট তার সম্পর্কিত ডেস্ট্রাক্টরকে ক্লিনআপ করার জন্য কল করবে না।

এটি §3.6.1 / 4 [বেসিক.স্টার্ট.ইনাইটে] প্রয়োগ করা হয়েছে :

বর্তমান ব্লকটি ছাড়াই প্রোগ্রামটি সমাপ্তি (উদাহরণস্বরূপ, ফাংশনটি স্ট্যান্ড :: প্রস্থান (ইনট) (18.5) কল করে স্বয়ংক্রিয় স্টোরেজ সময়কাল (12.4) সহ কোনও বস্তু ধ্বংস করে না । স্থিতিশীল বা থ্রেড স্টোরেজ সময়কাল সহ কোনও অবজেক্টের ধ্বংসের সময় যদি কোনও স্ট্যান্ড :: প্রস্থানকে কোনও প্রোগ্রামের সমাপ্তির জন্য বলা হয় তবে প্রোগ্রামটির অপরিবর্তিত আচরণ রয়েছে।

এখনই এটি সম্পর্কে চিন্তা করুন, আপনি কেন এমন কাজ করবেন? আপনি কতগুলি বস্তুর বেদনাদায়ক ক্ষতি করেছেন?

অন্যান্য [খারাপ হিসাবে] বিকল্প

কোনও প্রোগ্রাম বন্ধ করার অন্যান্য উপায় রয়েছে (ক্র্যাশ হওয়া ছাড়াও) তবে তাদের প্রস্তাব দেওয়া হয়নি। কেবল স্পষ্টতার স্বার্থে তারা এখানে উপস্থাপন করতে চলেছে। লক্ষ্য করুন কিভাবে স্বাভাবিক প্রোগ্রাম পরিসমাপ্তি না মানে স্ট্যাকের unwinding কিন্তু একটি ঠিক আছে অপারেটিং সিস্টেমের জন্য রাষ্ট্র।

  • std::_Exit একটি সাধারণ প্রোগ্রামের সমাপ্তি ঘটায় এবং এটিই।
  • std::quick_exitএকটি সাধারণ প্রোগ্রামের সমাপ্তি ঘটায় এবং std::at_quick_exitহ্যান্ডলারদের কল করে , অন্য কোনও ক্লিনআপ সম্পন্ন হয় না।
  • std::exitএকটি সাধারণ প্রোগ্রামের সমাপ্তি ঘটায় এবং তারপরে std::atexitহ্যান্ডলারদের কল করে । অন্যান্য ধরণের ক্লিনআপগুলি স্ট্যাটিক অবজেক্ট ডেস্ট্রাক্টরদের কল করার মতো করা হয়।
  • std::abortএকটি অস্বাভাবিক প্রোগ্রামের সমাপ্তি ঘটায়, কোনও ক্লিনআপ করা হয় না। প্রোগ্রামটি যদি সত্যিই, সত্যিই অপ্রত্যাশিতভাবে বন্ধ করা হয় তবে এটি বলা উচিত। এটি ওএসকে অস্বাভাবিক সমাপ্তির সংকেত ব্যতীত আর কিছুই করবে না। কিছু সিস্টেম এক্ষেত্রে একটি কোর ডাম্প সম্পাদন করে।
  • std::terminateকলগুলি std::terminate_handlerযা std::abortডিফল্টরূপে কল করে।

25
এটি বেশ তথ্যবহুল: উল্লেখযোগ্যভাবে আমি কখনই বুঝতে পারি নি যে একটি ব্যতিক্রম newছোঁয়া যা কোথাও পরিচালনা করা হয় না (উদাহরণস্বরূপ: কিছু নিক্ষেপ std::bad_allocএবং আপনার প্রোগ্রাম যে ব্যতিক্রমটি যে কোনও জায়গায় ধরতে ভুলে গেছে) সমাপ্তির আগে স্ট্যাকটি সঠিকভাবে উন্মুক্ত করবে না । এটি আমার কাছে নির্বোধ বলে মনে হচ্ছে: প্রয়োজনীয়ভাবে কলটিকে mainএকটি তুচ্ছ ঘটনাতে গুটিয়ে ফেলা সহজ হত try{- এই }catch(...){}ব্লকটি নিশ্চিত করে যে স্ট্যাক আনওয়াইন্ডিং সঠিকভাবে সম্পন্ন হয়েছে কোনও ক্ষেত্রে, বিনা ব্যয়ে (যার অর্থ: এটি ব্যবহার না করা প্রোগ্রামগুলি কোনও মূল্য দেবে না শাস্তি)। এটি সম্পন্ন না হওয়ার কোনও বিশেষ কারণ আছে কি?
মার্ক ভ্যান লিউউইন

12
@ মার্কওয়ানলিউউইন এর একটি সম্ভাব্য কারণ ডিবাগ করা: আপনি কোনও অপ্রয়োজনীয় ব্যতিক্রম ছড়িয়ে দেওয়ার সাথে সাথে আপনি ডিবাগারে প্রবেশ করতে চান। স্ট্যাকটি আনওয়াইন্ড করা এবং ক্লিনআপ করার ফলে আপনি যে ডিবাগ করতে চান তাতে ক্র্যাশ কী ঘটেছিল তার প্রসঙ্গে মুছে ফেলা হবে। কোনও ডিবাগার উপস্থিত না থাকলে কোর ডাম্প করা ভাল to যাতে পোস্টমর্টেম বিশ্লেষণ করা যায়।
হিউ অ্যালেন

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

2
@nwp, আমি অনুভূতিটি বুঝতে পারি understand তবে তাত্ক্ষণিকভাবে হত্যা করা ফাইলগুলিকে কলুষিত করতে পারে, আমার সাম্প্রতিক ট্যাবগুলি সংরক্ষণ করতে পারে না ইত্যাদি :)
পল ড্রাগার

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

61

মার্টিন ইয়র্ক যেমন উল্লেখ করেছেন, প্রস্থানটি রিটার্নের মতো প্রয়োজনীয় পরিষ্কার-পরিচ্ছন্নতা সম্পাদন করে না।

প্রস্থান করার জায়গায় রিটার্নটি ব্যবহার করা সর্বদা ভাল। আপনি যদি প্রধান না হন তবে আপনি যেখানেই প্রোগ্রামটি থেকে বেরিয়ে যেতে চান সেখানে প্রথমে ফিরে যান।

নীচের উদাহরণ বিবেচনা করুন। নিম্নলিখিত প্রোগ্রামের সাথে, উল্লিখিত সামগ্রীর সাথে একটি ফাইল তৈরি করা হবে। তবে যদি রিটার্নটি মন্তব্য করা হয় এবং নিরবিচ্ছিন্ন প্রস্থান (0) হয় তবে সংকলকটি আপনাকে আশ্বাস দেয় না যে ফাইলটিতে প্রয়োজনীয় পাঠ্য থাকবে।

int main()
{
    ofstream os("out.txt");
    os << "Hello, Can you see me!\n";
    return(0);
    //exit(0);
}

শুধু এটিই নয়, কোনও প্রোগ্রামে একাধিক প্রস্থান পয়েন্টগুলি ডিবাগিংকে আরও শক্ত করে তুলবে। যখন প্রযোজ্য হবে তখনই প্রস্থান ব্যবহার করুন।


2
কিছুটা বড় প্রোগ্রামে আপনি এই আচরণটি অর্জন করার জন্য কী পরামর্শ দিচ্ছেন? কোডের আরও গভীরতর কোথাও ত্রুটির শর্তটি উদ্ঘাটিত হয় যা প্রোগ্রামটি থেকে বেরিয়ে আসা উচিত, আপনি কীভাবে সর্বদা পরিষ্কারভাবে ফিরে আসবেন?
জানুস

5
@ জানুস, সেক্ষেত্রে আপনি ব্যতিক্রম / ছোঁড়া ব্যতিক্রমগুলি ব্যবহার করতে পারেন, যদি পূর্বনির্ধারিত মানটি না ফেরত দেয় যেমন, ফাংশন থেকে একটি রিটার্ন মান থাকতে পারে, যেমন সফল হলে রিটার্ন 0, ব্যর্থতার ক্ষেত্রে 1, তবে কার্যকর করা চালিয়ে যান , -1 ব্যর্থতার ক্ষেত্রে এবং প্রোগ্রামটি থেকে প্রস্থান করুন। ফাংশন থেকে প্রাপ্ত রিটার্ন মানটির ভিত্তিতে, যদি এটি ব্যর্থ হয় তবে আরও কোনও ক্লিন-আপ ক্রিয়াকলাপ সম্পাদন করে মূল থেকে ফিরে আসুন। অবশেষে, প্রস্থানটি বিনা বিচারে ব্যবহার করুন, আমি এড়াতে চাইছি না।
নরেন্দ্র এন

1
@ নরেন্দ্রএন, "প্রয়োজনীয় ক্লিনআপ" অস্পষ্ট - ওএস যত্ন নেবে (উইন্ডোজ / লিনাক্স) যে মেমরি এবং ফাইল হ্যান্ডলগুলি সঠিকভাবে প্রকাশিত হয়েছে। "অনুপস্থিত" ফাইল আউটপুট হিসাবে: আপনি যদি জোর দিয়ে থাকেন যে এটি একটি আসল সমস্যা হতে পারে তবে stackoverflow.com/questions/14105650/how-does-stdflush-work দেখুন আপনার যদি কোনও ত্রুটির শর্ত থাকে তবে সঠিক লগিং আপনাকে জানায় যে আপনার প্রোগ্রামটি অপরিবর্তিত অবস্থায় পৌঁছেছে এবং আপনি আপনার লগিং পয়েন্টের ঠিক আগে ব্রেক ব্রেকপয়েন্ট সেট করতে পারেন। কীভাবে এটি ডিবাগিংকে আরও শক্ত করে তোলে?
মার্কাস

2
মনে রাখবেন যে এই উত্তরটি একটি সি ++ প্রোগ্রামটি কীভাবে ছাড়বেন প্রশ্ন থেকে একত্রীকরণ করা হয়েছিল ? - এসও 1116493 । এই প্রশ্নটি জিজ্ঞাসা করার প্রায় 6 বছর আগে এই উত্তরটি লেখা হয়েছিল।
জোনাথন লেফলার

return (EXIT_SUCCESS);পরিবর্তে আধুনিক সি ++ ব্যবহারের জন্য return(0)
জোনাস স্টেইন

39

std::exitফাংশন কল করুন ।   


2
আপনি যখন এই ফাংশনটি কল করেন তখন কোন অবজেক্টের ডেস্ট্রাক্টররা ডাকা হয়?
রব কেনেডি

37
প্রস্থান () ফিরে আসে না। তাই কোনও স্ট্যাক আনওয়ানডিং জায়গা নিতে পারে না। এমনকি বিশ্বব্যাপী বস্তুও ধ্বংস হয় না। তবে অ্যাকেক্সিট () এর সাথে নিবন্ধিত ফাংশনগুলি কল করা হবে।
মার্টিন ইয়র্ক

16
exit()যখন আপনার লাইব্রেরি কোডটি আমার হোস্ট প্রক্রিয়াটির অভ্যন্তরে চলছে তখন কল করবেন না - দ্বিতীয়টি কোথাও মাঝখানে প্রস্থান করবে exit
শার্পথথ

5
মনে রাখবেন যে এই উত্তরটি একটি সি ++ প্রোগ্রামটি কীভাবে ছাড়বেন প্রশ্ন থেকে একত্রীকরণ করা হয়েছিল ? - এসও 1116493 । এই প্রশ্নটি জিজ্ঞাসা করার প্রায় 6 বছর আগে এই উত্তরটি লেখা হয়েছিল।
জোনাথন লেফলার

23

লোকেরা "কল প্রস্থান (রিটার্ন কোড)" বলছে, তবে এটি খারাপ ফর্ম। ছোট প্রোগ্রামগুলিতে এটি ঠিক আছে, তবে এটির সাথে বেশ কয়েকটি সমস্যা রয়েছে:

  1. আপনি প্রোগ্রাম থেকে একাধিক প্রস্থান পয়েন্ট শেষ হবে
  2. এটি কোডটিকে আরও সংশ্লেষিত করে তোলে (গোটো ব্যবহারের মতো)
  3. এটি রানটাইমে বরাদ্দ থাকা মেমরি প্রকাশ করতে পারে না

সত্যই, সমস্যাটি থেকে বেরিয়ে আসার একমাত্র সময়টি এই মূল লাইনটি মেইন.কেপ্পে রয়েছে:

return 0;

আপনি যদি ত্রুটিগুলি পরিচালনা করতে প্রস্থান () ব্যবহার করে থাকেন তবে আপনাকে আরও মার্জিত এবং নিরাপদ পদ্ধতি হিসাবে ব্যতিক্রমগুলি (এবং নেস্টিং ব্যতিক্রমগুলি) সম্পর্কে শিখতে হবে।


9
মাল্টি-থ্রেড এনভায়রনমেন্টে, আলাদা থ্রেডে ফেলে দেওয়া একটি ব্যতিক্রম মূল () হলেও হ্যান্ডেল করা হবে না - অধীনস্থ থ্রেডের মেয়াদ শেষ হওয়ার আগে কিছু ম্যানুয়াল ক্রস-থ্রেড যোগাযোগের প্রয়োজন হয়।
স্টিভ গিলহাম

3
১ এবং ২ প্রোগ্রামার পর্যন্ত, সঠিক লগিংয়ের সাথে এটি কোনও সমস্যা নয় কারণ অব্যাহতি চিরকালের জন্য বন্ধ হয়ে যায়। 3 হিসাবে: এটি কেবল সাধারণ ভুল, ওএস মেমোরিটি মুক্ত করবে - সম্ভবত এমবেডড ডিভাইস / রিয়েলটাইম বাদ দিলেও আপনি যদি এটি করছেন তবে আপনি সম্ভবত আপনার জিনিসগুলি জানেন।
মার্কাস

1
মনে রাখবেন যে এই উত্তরটি একটি সি ++ প্রোগ্রামটি কীভাবে ছাড়বেন প্রশ্ন থেকে একত্রীকরণ করা হয়েছিল ? - এসও 1116493 । এই প্রশ্নটি জিজ্ঞাসা করার প্রায় 6 বছর আগে এই উত্তরটি লেখা হয়েছিল।
জোনাথন লেফলার

1
যদিও কোনও ত্রুটি ঘটেছে, তবে আপনাকে 0 ফেরত দেওয়া উচিত নয় You আপনাকে 1 (বা সম্ভবত অন্য কোনও মান, তবে 1 সর্বদা একটি নিরাপদ পছন্দ) ফেরত দেওয়া উচিত।
কেফ শেকটার

14

return 0;আপনি যেখানেই চান সেখানে রাখুন int main()এবং প্রোগ্রামটি তত্ক্ষণাত বন্ধ হয়ে যাবে।


দ্য নাইটম্যান, @ ইভান-কারস্লেক এবং অন্য সবাই, আমি আরও যোগ করব যে এই এই প্রশ্নটি # 36707 একটি রুটিনে যে কোনও জায়গায় রিটার্ন স্টেটমেন্টটি ঠিক কোথাও হওয়া উচিত কিনা তা নিয়ে একটি আলোচনা দেয়। এটি একটি সমাধান; তবে নির্দিষ্ট পরিস্থিতির উপর নির্ভর করে আমি বলব না এটিই সেরা সমাধান solution
লোকালহোস্ট

1
ওপি এই সম্পর্কে কিছুই বলেনি, সুতরাং আমি মনে করি এটি কোডটি ফাংশনের অভ্যন্তরেই বোঝানো উচিত বলে মনে করা বরং ফুসকুড়ি main
মার্ক ভ্যান লিউউইন

@ লোকালহোস্ট কোনও পরিস্থিতিতে কোনও রিটার্নের বিবৃতি সম্পূর্ণরূপে alচ্ছিক। তবে, int main()ভিন্ন। প্রোগ্রামটি int main()শুরু এবং শেষ হতে ব্যবহার করে। এটি করার অন্য কোনও উপায় নেই। আপনি সত্য বা মিথ্যা ফিরে না আসা পর্যন্ত প্রোগ্রামটি চলবে। প্রায় 1 বার বা সত্য ফিরে আসার সময়, প্রোগ্রামটি সঠিকভাবে বন্ধ হয়ে গেছে তা নির্দেশ করার জন্য (উদাহরণস্বরূপ: আপনি মেমরি মুক্ত করতে না পারলে বা যে কোনও কারণেই মিথ্যা ব্যবহার করতে পারেন)) প্রোগ্রামটি নিজেই চালিয়ে দেওয়া সর্বদা একটি খারাপ ধারণা, উদাহরণস্বরূপ:int main() { int x = 2; int foo = x*5; std::cout << "blah"; }
ইভান কারস্লেক

@ ইভানকার্লস্ক বুঝেছেন, যদি আপনি এই প্রশ্নের জন্য আমি অন্য কোথাও পোস্ট করা কোনও মন্তব্য লক্ষ্য করেন তবে আমি এ সম্পর্কে পরিচিত int main; যাইহোক, একটি প্রধান রুটিনে একাধিক রিটার্ন স্টেটমেন্ট থাকা ভাল ধারণা নয়। একটি সম্ভাব্য সতর্কতামূলক কোড পাঠযোগ্যতা উন্নত করা; তবে, বুলিয়ান পতাকাের মতো কিছু ব্যবহার করে যা কিছু নির্দিষ্ট কোড বিভাগের অ্যাপ্লিকেশন অবস্থায় চলমান থেকে রোধ করতে রাষ্ট্র পরিবর্তন করে। ব্যক্তিগতভাবে, আমি দেখতে পাই একটি সাধারণ রিটার্ন স্টেটমেন্ট বেশিরভাগ অ্যাপ্লিকেশনকে আরও পাঠযোগ্য করে তোলে। শেষ অবধি, প্রস্থান করার আগে মেমরি ক্লিনআপ এবং I / O অবজেক্টগুলি সঠিকভাবে বন্ধ করা সম্পর্কে প্রশ্ন।
লোকালহোস্ট

2
@ ইভানকার্লস্ক আপনি একটি সঠিক সমাপ্তি নির্দেশক trueথেকে ফিরে আসবেন না main। সাধারণ সমাপ্তি নির্দেশ করতে আপনাকে অবশ্যই শূন্য বা EXIT_SUCCESS(অথবা, আপনি চাইলে false, যা স্পষ্টত শূন্যে রূপান্তরিত হবে) ফিরে আসতে হবে। ব্যর্থতা নির্দেশ করতে আপনি ফিরে আসতে পারেন EXIT_FAILURE। অন্য কোনও কোড অর্থ বাস্তবায়ন-সংজ্ঞায়িত (POSIX সিস্টেমে এর অর্থ আসল ত্রুটি কোড হবে)।
রুসলান

11

কার্যকর কার্যপ্রবাহটি মূল ফাংশনের শেষের দিকে পৌঁছে গেলে প্রোগ্রামটি শেষ হবে।

এর আগে এটি বন্ধ করতে, আপনি প্রস্থান (ইনট স্ট্যাটাস) ফাংশনটি ব্যবহার করতে পারেন, যেখানে স্ট্যাটাসটি প্রোগ্রামটি শুরু করে যা কিছুতেই ফিরে আসে is 0 সাধারণত একটি ত্রুটিবিহীন অবস্থা নির্দেশ করে


2
মনে রাখবেন যে এই উত্তরটি একটি সি ++ প্রোগ্রামটি কীভাবে ছাড়বেন প্রশ্ন থেকে একত্রীকরণ করা হয়েছিল ? - এসও 1116493 । এই প্রশ্নটি জিজ্ঞাসা করার প্রায় 6 বছর আগে এই উত্তরটি লেখা হয়েছিল।
জনাথন লেফলার

11

হয় আপনার কাছ থেকে কোনও মান ফেরত দিন mainবা exitফাংশনটি ব্যবহার করুন । উভয় একটি int গ্রহণ। আপনি যদি কোনও বাহ্যিক প্রক্রিয়া না দেখায় রিটার্নের মানটি না দেখেন তবে আপনি কী মান প্রত্যাবর্তন করেন তা সত্যিই গুরুত্বপূর্ণ নয়।


3
মনে রাখবেন যে এই উত্তরটি একটি সি ++ প্রোগ্রামটি কীভাবে ছাড়বেন প্রশ্ন থেকে একত্রীকরণ করা হয়েছিল ? - এসও 1116493 । এই প্রশ্নটি জিজ্ঞাসা করার প্রায় 6 বছর আগে এই উত্তরটি লেখা হয়েছিল।
জনাথন লেফলার

11

কোডটির গভীরতর কোথাও যদি আপনার একটি ত্রুটি থাকে তবে হয় ব্যতিক্রম নিক্ষেপ করুন বা ত্রুটি কোড সেট করুন। ত্রুটি কোডগুলি সেট করার পরিবর্তে একটি ব্যতিক্রম ছুঁড়ে ফেলা ভাল।


2
মনে রাখবেন যে এই উত্তরটি একটি সি ++ প্রোগ্রামটি কীভাবে ছাড়বেন প্রশ্ন থেকে একত্রীকরণ করা হয়েছিল ? - এসও 1116493 । এই প্রশ্নটি জিজ্ঞাসা করার প্রায় 6 বছর আগে এই উত্তরটি লেখা হয়েছিল।
জনাথন লেফলার

9

সাধারণত আপনি exit()উপযুক্ত প্রস্থান স্থিতি সহ পদ্ধতিটি ব্যবহার করবেন ।

জিরো মানে একটি সফল রান। একটি শূন্য-স্থিতি ইঙ্গিত দেয় যে একরকম সমস্যা দেখা দিয়েছে। কোনও প্রসেসটি সফলভাবে চলেছে কিনা তা নির্ধারণ করতে এই প্রস্থান কোডটি প্যারেন্ট প্রসেসগুলি (যেমন শেল স্ক্রিপ্ট) দ্বারা ব্যবহৃত হয়।


1
প্রস্থান মায়া ব্যবহারের অর্থ আপনার কোনও ডিজাইনের সমস্যা আছে। যদি কোনও প্রোগ্রামটি সঠিকভাবে বিভাজন করে তবে এটি কেবল যখন প্রধান হবে তখনই শেষ করা উচিত return 0;। আমি ধরে নিয়েছি এর exit()মত assert(false);এবং তাই প্রাথমিক পর্যায়ে সমস্যাগুলি ধরায় উন্নয়নের ক্ষেত্রে এটি ব্যবহার করা উচিত।
কফডেভলপার

2
মনে রাখবেন যে এই উত্তরটি একটি সি ++ প্রোগ্রামটি কীভাবে ছাড়বেন প্রশ্ন থেকে একত্রীকরণ করা হয়েছিল ? - এসও 1116493 । এই প্রশ্নটি জিজ্ঞাসা করার প্রায় 6 বছর আগে এই উত্তরটি লেখা হয়েছিল।
জনাথন লেফলার

7

প্রস্থান কল করার বাইরেও (ত্রুটি_কোড) - যা অ্যাক্সিট হ্যান্ডলারগুলিকে কল করে, তবে আরআইআইআই ডেস্ট্রাক্টর ইত্যাদি না - আরও বেশি করে আমি ব্যতিক্রম ব্যবহার করছি।

আরও বেশি করে আমার মূল প্রোগ্রামটি দেখতে ভাল লাগে

int main(int argc, char** argv) 
{
    try {
        exit( secondary_main(argc, argv );
    }
    catch(...) {
        // optionally, print something like "unexpected or unknown exception caught by main"
        exit(1);
    }
}

যেখানে গৌণ_মাইন যেখানে মূলত সমস্ত স্টাফ রাখা হয়েছিল - অর্থাত্ মূল মূলটির নাম পরিবর্তন করা হবে মাধ্যমিক_মিন এবং উপরের স্টাব মেইনটি যুক্ত করা হয়েছে। এটি মাত্র এক নব্বইটি, যাতে ট্রে এবং মূল ধরার মধ্যে খুব বেশি কোড না থাকে।

আপনি যদি চান তবে অন্যান্য ব্যতিক্রমের ধরণগুলি ধরুন।
আমি স্ট্রিং ত্রুটির ধরণের ধরণগুলি স্ট্যান্ড :: স্ট্রিং বা চর * এর মতো এবং মূলত ক্যাচ হ্যান্ডলারের মুদ্রণ পছন্দ করি।

এটির মতো ব্যতিক্রমগুলি অন্তত RAII ডেস্ট্রাক্টরদের কল করার অনুমতি দেয়, যাতে তারা ক্লিনআপ করতে পারে। যা আনন্দদায়ক এবং দরকারী হতে পারে।

সামগ্রিকভাবে, সি ত্রুটি পরিচালনা - প্রস্থান এবং সিগন্যালগুলি - এবং সি ++ ত্রুটি হ্যান্ডলিং - চেষ্টা করুন / ধরা / নিক্ষেপ ব্যতিক্রম - একসাথে অসামঞ্জস্যভাবে খেলুন।

তারপরে, যেখানে আপনি একটি ত্রুটি সনাক্ত করেন

throw "error message"

বা আরও কিছু নির্দিষ্ট ব্যতিক্রম প্রকার।


উপায় দ্বারা: আমি ভালভাবে জানি যে স্ট্রিংয়ের মতো ডেটা টাইপ ব্যবহার করা, যা গতিশীল মেমরির বরাদ্দকে জড়িত করতে পারে, ব্যতিক্রমগুলির জন্য কোনও ব্যতিক্রম হ্যান্ডলার বা তার চারপাশে কোনও ভাল ধারণা নয় যা মেমরির বাইরে চলে যাওয়ার সাথে সম্পর্কিত হতে পারে। সি স্টাইলের স্ট্রিং কনস্ট্যান্ট কোনও সমস্যা নয় are
ক্রেজি গ্লিউ

1
exitআপনার প্রোগ্রামে কল করার কোনও মানে নেই । আপনি যেহেতু প্রবেশ করছেন main, আপনি ঠিক করতে পারেন return exitCode;
রুসলান

-1

আপনার যদি বিবৃতিটি লুপে থাকে তবে আপনি ব্যবহার করতে পারেন

 break; 

আপনি যদি কিছু কোড থেকে বাঁচতে চান এবং লুপ চালিয়ে যেতে চান তবে ব্যবহার করুন:

অবিরত;

আপনার যদি বিবৃতিটি লুপে না থাকে আপনি ব্যবহার করতে পারেন:

 return 0;

Or 




  exit();

-2

ডুড ... exit()ফাংশনটি stdlib.h এর অধীনে সংজ্ঞায়িত করা হয়েছে

সুতরাং আপনার একটি প্রিপ্রেসেসর যুক্ত করা দরকার।

include stdlib.hশিরোনাম বিভাগে রাখুন

তারপরে exit();আপনি যেখানে পছন্দ করেন সেখানে ব্যবহার করুন তবে প্রস্থানের প্রথম বন্ধনে একটি সংখ্যার সংখ্যা লিখতে ভুলবেন না।

উদাহরণ স্বরূপ:

exit(0);

-2

যদি আমি যে শর্তটি পরীক্ষা করছি তা যদি সত্যিই খারাপ খবর হয় তবে আমি এটি করি:

*(int*) NULL= 0;

এটি আমাকে একটি দুর্দান্ত করডাম্প দেয় যেখানে থেকে আমি পরিস্থিতিটি পরীক্ষা করতে পারি।


4
এটি অপ্টিমাইজড হতে পারে, কারণ এটি অপরিজ্ঞাত আচরণের কারণ হয়। প্রকৃতপক্ষে, এই ধরনের বিবৃতি থাকা মৃত্যুদণ্ডের পুরো শাখাটি সংকলক দ্বারা মুছে ফেলা যায়।
রুসলান

-2

শর্ত ভঙ্গ করতে রিটার্ন (0) ব্যবহার করুন;

সুতরাং, আপনার ক্ষেত্রে এটি হবে:

    if(x==1)
    {
        return 0;
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.