ফাংশনের স্বাক্ষরে কীওয়ার্ডটি নিক্ষেপ করুন


199

কোন throwফাংশনের স্বাক্ষরে সি ++ কীওয়ার্ড ব্যবহার করা খারাপ অভ্যাস হিসাবে বিবেচিত হওয়ার প্রযুক্তিগত কারণ কী ?

bool some_func() throw(myExc)
{
  ...
  if (problem_occurred) 
  {
    throw myExc("problem occurred");
  }
  ...
}

: এই সাম্প্রতিক সংশ্লিষ্ট প্রশ্ন দেখতে পাবেন stackoverflow.com/questions/1037575/...
laalto


1
কি noexceptকিছু পরিবর্তন?
অ্যারন ম্যাকডেইড

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

এটি উল্লেখ করা উচিত যে ব্যতিক্রমের স্পেসিফিকেশনগুলি সি ++ 11 সাল থেকে অবচিত করা হয়েছে।
ফ্রানসোয়া অ্যান্ডরিয়াক্স

উত্তর:


127

না, এটি ভাল অনুশীলন হিসাবে বিবেচিত হয় না। বিপরীতে, এটি সাধারণত একটি খারাপ ধারণা হিসাবে বিবেচিত হয়।

http://www.gotw.ca/publications/mill22.htm কেন তা সম্পর্কে আরও বিশদে চলে যায়, তবে সমস্যাটি আংশিক যে সংকলক এটি প্রয়োগ করতে অক্ষম, তাই এটি রানটাইম এ চেক করতে হবে, যা সাধারণত অবাঞ্ছিত। এবং এটি কোনও ক্ষেত্রেই সমর্থনযোগ্য নয়। (এমএসভিসি ব্যতিক্রম স্পেসিফিকেশনগুলি উপেক্ষা করে, থ্রো () বাদে, যা এটি গ্যারান্টি হিসাবে ব্যাখ্যা করে যে কোনও ব্যতিক্রম ছোঁড়া হবে না।


25
হ্যাঁ. আপনার কোডে সাদা (স্পেস) যুক্ত হওয়ার চেয়ে আরও ভাল উপায় রয়েছে (মাইএক্স)।
আসফ লাভি

4
হ্যাঁ, কেবলমাত্র ব্যতিক্রমের নির্দিষ্টকরণগুলি আবিষ্কার করে এমন লোকেরা প্রায়শই ধরে নেয় যে তারা জাভার মতো কাজ করে, যেখানে সংকলক তাদের প্রয়োগ করতে সক্ষম। সি ++ এ, এটি ঘটবে না, যা তাদেরকে অনেক কম দরকারী করে তোলে।
jalf

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

1
@ অ্যান্ডারলিন্ডন কী ডকুমেন্টেটিভ উদ্দেশ্য? আপনি যদি কেবল আপনার কোডের আচরণটি নথিভুক্ত করতে চান তবে তার উপরে একটি মন্তব্য দিন। আপনি দ্বিতীয় অংশটি দিয়ে কী বোঝাতে চাইছেন তা নিশ্চিত নয়। ব্যতিক্রম আপনি চেষ্টা করলেও কখনই ধরতে পারবেন না?
jalf

4
আপনার কোডটি নথিভুক্ত করার ক্ষেত্রে কোডটি শক্তিশালী বলে আমি মনে করি। (মন্তব্য মিথ্যা বলতে পারেন)। আমি যে "ডকুমেন্টেটিভ" ইফেক্টটির উল্লেখ করছি সেটি হ'ল আপনি নিশ্চিতভাবে জানতে পারবেন কোনটি ব্যতিক্রম আপনি ধরতে পারবেন এবং অন্যরাও তা হতে পারবেন না।
অ্যান্ডারস লিন্ডন

57

জলফ ইতোমধ্যে এর সাথে যুক্ত রয়েছে, তবে ব্যর্থতার উল্লেখগুলি কেন আশা করা যায় তত কার্যকর নয় কেন এটি জিওটিডাব্লু একে একে খুব সুন্দরভাবে জানিয়েছে:

int Gunc() throw();    // will throw nothing (?)
int Hunc() throw(A,B); // can only throw A or B (?)

মন্তব্যগুলি কি সঠিক? বেশ না। Gunc()সত্যিই কিছু ফেলে দিতে পারে এবং Hunc()এ বা বি বাদ দিয়ে অন্য কিছু ভালভাবে ফেলে দিতে পারে! সংকলক কেবল বোধহয় তাদেরকে বেহাল করার গ্যারান্টি দেয় ... ওহ, এবং বেশিরভাগ সময় আপনার প্রোগ্রামকে বুদ্ধিহীনভাবে পরাজিত করে।

এটি ঠিক তেমনই নেমে আসে, আপনি সম্ভবত একটি কল terminate()এবং আপনার প্রোগ্রামটি দ্রুত কিন্তু বেদনাদায়ক মৃত্যুতে মারা যাবেন ।

জিওটিডাব্লুসের উপসংহারটি হ'ল:

সুতরাং এখানে একটি সম্প্রদায় হিসাবে আমরা আজকের মতো শিখেছি সেরা পরামর্শ বলে মনে হচ্ছে:

  • নৈতিক # 1: কোনও ব্যতিক্রমের স্পেসিফিকেশন কখনই লিখবেন না।
  • নৈতিক # 2: সম্ভবত একটি খালিটি বাদে, তবে আমি যদি আপনি থাকতাম তবে আমি এগুলি এড়াতেও চাইতাম।

1
আমি নিশ্চিত না যে আমি কেন একটি ব্যতিক্রম ছুঁড়ে দেব এবং এটি উল্লেখ করতে সক্ষম হব না। এমনকি যদি এটি অন্য ফাংশন দ্বারা ছুঁড়ে ফেলা হয় তবে আমি জানি কী কী ব্যতিক্রম ছোঁড়া যায়। কেবলমাত্র আমি দেখতে পাচ্ছি কারণ এটি ক্লান্তিকর।
মাস্টারমাস্টিক

3
@ কেন: কথাটি হ'ল ব্যতিক্রমের স্পেসিফিকেশন লেখার বেশিরভাগ নেতিবাচক ফলাফল রয়েছে। একমাত্র ইতিবাচক প্রভাবটি হ'ল এটি প্রোগ্রামারটিকে ব্যতিক্রমগুলি কী ঘটতে পারে তা দেখায়, তবে যেহেতু এটি কম্পাইলার দ্বারা যুক্তিযুক্তভাবে পরীক্ষা করা হয়নি এটি ত্রুটিগুলির ঝুঁকিতে পড়ে এবং তাই এর পক্ষে খুব বেশি মূল্যবান নয়।
sth

1
ওহ ঠিক আছে, সাড়া দেওয়ার জন্য ধন্যবাদ। আমার মনে হয় ডকুমেন্টেশন এর জন্য এটিই।
মাস্টারমাস্টিক

2
সঠিক না. ব্যতিক্রমের স্পেসিফিকেশন লিখতে হবে, তবে কলটিটি কলকারীর কী ত্রুটিগুলি ধরার চেষ্টা করা উচিত তা যোগাযোগ করার ধারণা।
হ্যালো ওয়ার্ল্ড

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

30

এই প্রশ্নের সাথে অন্য সমস্ত প্রশ্নের উত্তরকে আরও কিছুটা যুক্ত করতে, প্রশ্নটিতে কয়েক মিনিট বিনিয়োগ করা উচিত: নিম্নলিখিত কোডটির আউটপুট কী?

#include <iostream>
void throw_exception() throw(const char *)
{
    throw 10;
}
void my_unexpected(){
    std::cout << "well - this was unexpected" << std::endl;
}
int main(int argc, char **argv){
    std::set_unexpected(my_unexpected);
    try{
        throw_exception();
    }catch(int x){
        std::cout << "catch int: " << x << std::endl;
    }catch(...){
        std::cout << "catch ..." << std::endl;
    }
}

উত্তর: এখানে উল্লিখিত হিসাবে , প্রোগ্রামটি কল করে std::terminate()এবং এইভাবে ব্যতিক্রম হ্যান্ডলারদের কেউই কল করবে না।

বিশদ: প্রথম my_unexpected()ফাংশন বলা হয়, তবে যেহেতু এটি throw_exception()ফাংশন প্রোটোটাইপের জন্য কোনও মিলের ব্যতিক্রম প্রকারটিকে আবার নিক্ষেপ করে না , শেষে std::terminate()বলা হয়। সুতরাং সম্পূর্ণ আউটপুট এইরকম দেখাচ্ছে:

ব্যবহারকারীর @ ব্যবহারকারী: ~ / tmp $ g ++ -o ছাড়া.Etete.test.cpp
ব্যবহারকারীর @ ব্যবহারকারী: ~ / tmp / ./except.test
ভাল -
এটি 'অন্তর্গত' বাতিল একটি উদাহরণ ফেলে দেওয়ার পরে অপ্রত্যাশিত সমাপ্তি বলা হত
(কোর ডাম্প)


12

নিক্ষেপ স্পেসিফায়ারের একমাত্র ব্যবহারিক প্রভাবটি হ'ল যদি myExcআপনার ফাংশন থেকে আলাদা কিছু ফেলে দেওয়া হয় std::unexpectedতবে ডাকা হবে (সাধারণ আনহানডেল ব্যতিক্রম পদ্ধতির পরিবর্তে)।

কোনও ফাংশন যে ধরণের ব্যতিক্রম ছুঁড়ে ফেলতে পারে ডকুমেন্ট করতে আমি সাধারণত এটি করি:

bool
some_func() /* throw (myExc) */ {
}

5
এটি উল্লেখ করাও দরকারী যে স্টাড :: অপ্রত্যাশিত () এর কল সাধারণত স্টাড :: টার্মিনেট () এবং আপনার প্রোগ্রামের আকস্মিক কলটিতে কল দেয়।
sth

1
- এবং এমএসভিসি অন্তত আমি যতদূর জানি এই আচরণটি প্রয়োগ করে না।
জালফ

9

যখন ভাষাতে নিক্ষেপ সংক্রান্ত স্পেসিফিকেশন যুক্ত হত তখন এটি সর্বোত্তম উদ্দেশ্য ছিল, তবে অনুশীলনটি আরও ব্যবহারিক পদ্ধতির জন্ম নিয়েছে।

সি ++ সহ আমার সাধারণ নিয়মটি কেবল কোনও পদ্ধতি নিক্ষেপ করতে পারে না তা বোঝাতে কেবল নিক্ষেপ নির্দিষ্টকরণ ব্যবহার করা। এটি একটি দৃ guarantee় গ্যারান্টি। অন্যথায়, ধরে নিন এটি কিছু ফেলে দিতে পারে।


9

ঠিক আছে, এই নিক্ষেপ নির্দিষ্টকরণ সম্পর্কে গুগল করার সময় আমার এই নিবন্ধটি একবার দেখুন: - ( http://blogs.msdn.com/b/larryosterman/archive/2006/03/22/558390.aspx )

আমি এখানেও এর একটি অংশ পুনরুত্পাদন করছি, যাতে উপরের লিঙ্কটি কাজ করে বা না তা নির্বিশেষে ভবিষ্যতে এটি ব্যবহার করা যায়।

   class MyClass
   {
    size_t CalculateFoo()
    {
        :
        :
    };
    size_t MethodThatCannotThrow() throw()
    {
        return 100;
    };
    void ExampleMethod()
    {
        size_t foo, bar;
        try
        {
            foo = CalculateFoo();
            bar = foo * 100;
            MethodThatCannotThrow();
            printf("bar is %d", bar);
        }
        catch (...)
        {
        }
    }
};

সংকলকটি "থ্রো ()" বৈশিষ্ট্য সহ এটি দেখলে, সংকলকটি "বার" পরিবর্তনশীলটিকে সম্পূর্ণরূপে অনুকূল করতে পারে, কারণ এটি জানে যে মেথডথট্যানক্যানট্রো () থেকে কোনও ব্যতিক্রম ছোঁড়ার কোনও উপায় নেই। থ্রো () বৈশিষ্ট্য ব্যতীত, সংকলকটিকে "বার" ভেরিয়েবল তৈরি করতে হবে, কারণ মেথডথ্যাটক্যানটট্রো যদি ব্যতিক্রম ছুঁড়ে ফেলে, ব্যতিক্রম হ্যান্ডলার বার ভেরিয়েবলের মানের উপর নির্ভর করতে পারে / করবে।

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


3

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

সঙ্গে কিছু কম্পাইলার নন-ইনলাইন ফাংশনগুলিতে নো-থ্রোল স্পেসিফিকেশন উপকারী হতে পারে যদি সঠিক অনুকূলতা তৈরি হয় এবং সেই ফাংশনটির ব্যবহার পারফরম্যান্সকে এমনভাবে প্রভাবিত করে যে এটি তার ন্যায্যতা প্রমাণ করে।

আমার কাছে মনে হচ্ছে এটি ব্যবহার করা উচিত বা না, কোনও পারফরম্যান্স অপটিমাইজেশন চেষ্টার অংশ হিসাবে সম্ভবত প্রোফাইলিং সরঞ্জামগুলি ব্যবহার করে একটি অত্যন্ত সমালোচিত চোখের কল।

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

ব্যতিক্রম-নির্দিষ্টকরণের যুক্তি

ব্যতিক্রম স্পেসিফিকেশন [আইএসও 15.4] কখনও কখনও কোন ব্যতিক্রম নিক্ষিপ্ত হতে পারে তা নির্দেশ করার জন্য কোড করা হয় বা প্রোগ্রামার আশা করে যে তারা কার্য সম্পাদন করবে improve তবে স্মার্ট পয়েন্টার থেকে নিম্নলিখিত সদস্যটিকে বিবেচনা করুন:

টি ও অপারেটর * () কনট থ্রো () {রিটার্ন * পিটিআর; }

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

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

যদিও প্রাথমিকভাবে আবেদন করা যায়, একটি ব্যতিক্রম-নির্দিষ্টকরণের এমন পরিণতি ঘটে যা বোঝার জন্য খুব সতর্ক চিন্তা প্রয়োজন। ব্যতিক্রম-স্পেসিফিকেশনগুলির সাথে সবচেয়ে বড় সমস্যাটি হ'ল প্রোগ্রামাররা সেগুলিকে ব্যবহার করে যদিও প্রোগ্রামার তাদের পছন্দসই প্রভাব রাখে, প্রকৃতপক্ষে তার প্রভাবের পরিবর্তে।

একটি অন-ইনলাইন ফাংশন হ'ল এক জায়গায় "কিছুই নিক্ষেপ করে না" ব্যতিক্রম-নির্দিষ্টকরণের কিছু সংকলকগুলির সাথে কিছু সুবিধা থাকতে পারে।


1
"ব্যতিক্রম-নির্দিষ্টকরণের ক্ষেত্রে সবচেয়ে বড় সমস্যাটি হ'ল প্রোগ্রামাররা সেগুলিকে ব্যবহার করে যদিও প্রোগ্রামার তাদের পছন্দসই প্রভাব রাখে, প্রকৃতপক্ষে তার প্রভাবের পরিবর্তে।" মেশিন বা লোকের সাথে যোগাযোগ করার সময় এটি ত্রুটির # 1 কারণ: আমরা যা বলি এবং আমাদের অর্থ কী তার মধ্যে তফাত।
থাগোমাইজার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.