সি ++ এ ব্যতিক্রমের আইডেম্যাটিক ব্যবহার


16

Isocpp.org ব্যতিক্রম প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী রাজ্যের

কোনও ফাংশন ব্যবহারের ক্ষেত্রে কোডিং ত্রুটি চিহ্নিত করতে থ্রো ব্যবহার করবেন না। প্রক্রিয়াটিকে একটি ডিবাগারে প্রেরণ করতে বা প্রক্রিয়াটি ক্র্যাশ করতে এবং বিকাশকারীকে ডিবাগ করার জন্য ক্র্যাশ ডাম্প সংগ্রহ করতে দৃsert়তা বা অন্যান্য প্রক্রিয়া ব্যবহার করুন।

অন্যদিকে স্ট্যান্ডার্ড লাইব্রেরি স্ট্যান্ড :: লজিক_অরর এবং এর সমস্ত ডেরাইভেটিভস সংজ্ঞায়িত করেছে, যা আমার কাছে মনে হয় তারা অন্যান্য জিনিসগুলি ছাড়াও, প্রোগ্রামিং ত্রুটিগুলি হ্যান্ডেল করার কথা বলে। Std :: stof এ ফাঁকা স্ট্রিং পাস করা (অবৈধ_আরগমেন্টটি ফেলে দেবে) কোনও প্রোগ্রামিং ত্রুটি নয়? স্ট্রিং যা '1' / '0' এর চেয়ে বিভিন্ন অক্ষর সমেত স্টাড :: বিটসেটে (অবৈধ_আরগমেন্টটি ফেলে দেবে) কোনও প্রোগ্রামিং ত্রুটি নয়? Std :: বিটসেট :: কে কোনও অবৈধ সূচকের সাথে সেট করা (আউট_ফ_আরেঞ্জ করা হবে) কোনও প্রোগ্রামিং ত্রুটি নয়? যদি এটি না হয় তবে প্রোগ্রামিং ত্রুটিটি কীসের জন্য পরীক্ষা করা উচিত? স্ট্যান্ড :: বিটসেট স্ট্রিং-ভিত্তিক কনস্ট্রাক্টর কেবল সি ++ 11 সাল থেকেই বিদ্যমান, সুতরাং এটি ব্যতিক্রমগুলি মাথায় রেখে ব্যবহারের নকশা করা উচিত ছিল। অন্যদিকে আমার কাছে লোকেরা জানিয়েছিল যে লজিক_অরররটি মূলত ব্যবহার করা উচিত নয়।

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

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


6
আপনাকে সেই FAQ এন্ট্রিটি খুব সাবধানে পড়তে হবে এটি কেবল কোডিং ত্রুটিগুলিতেই প্রয়োগ হয় , অবৈধ ডেটা নয়, নাল বস্তুটিকে ডিফেরেন্সিং করে বা সাধারণ রানটাইম ব্যাডিয়াসহ কিছু করার থাকে। সাধারণভাবে, জোর দেওয়াগুলি এমন জিনিসগুলি সনাক্ত করা যা কখনই ঘটে না। অন্য কিছুর জন্য, ব্যতিক্রম, ত্রুটি কোড এবং আরও রয়েছে।
রবার্ট হার্ভে

1
@ রবার্টহারভে যে সংজ্ঞায় এখনও একই সমস্যা রয়েছে - যদি মানুষের হস্তক্ষেপ ছাড়াই কিছু সমাধান করা যায় বা না হয় তবে কেবল কোনও প্রোগ্রামের উপরের স্তরগুলিই এটি জানেন।
কুকি 451

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

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

2
যা আমার তত্ত্বের কাছে বিশ্বাসযোগ্যতা দেয় যে এই জাতীয় নিয়মটি আসলে বিদ্যমান থাকতে পারে না। আমি সি ++ লাউঞ্জ থেকে কিছু লোককে আমন্ত্রণ জানিয়েছি তারা যদি আপনার প্রশ্নের উত্তর দিতে পারে কিনা তা দেখার জন্য, যদিও আমি সেখানে everyুকি প্রত্যেকবারই তাদের পরামর্শটি "সি ++ ব্যবহার বন্ধ করুন, এটি আপনার মস্তিষ্ককে ভাজবে।" সুতরাং তাদের পরামর্শ নিন নিজের ঝুঁকিতে।
রবার্ট হার্ভে

উত্তর:


15

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

আমাকে ভুল করবেন না: ডিজাইনের কিছু অংশ রয়েছে যা বেশ সুন্দরভাবে কাজ করেছে এবং সি ++ এর জন্য কীভাবে ব্যতিক্রম শ্রেণিবদ্ধ নকশা করা যায় তার উদাহরণগুলি উদাহরণস্বরূপ রয়েছে (উদাহরণস্বরূপ, অন্যান্য শ্রেণীর তুলনায় তারা সবাই ভাগ করে নেয়) সাধারণ মূল)।

বিশেষভাবে তাকান logic_error, আমাদের কিছুটা ধাঁধা আছে। এক দিকে, যদি আপনার যদি বিষয়টিতে কোনো যুক্তিসংগত উপায় নেই, উপদেশ উদ্ধৃত অধিকার হল: এটা সাধারণত দ্রুত এবং সশব্দে যতটা সম্ভব ব্যর্থ সেরা তাই এটি debugged এবং সংশোধন করা যেতে পারে।

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

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

নির্দিষ্ট ধরণের ত্রুটিগুলির প্রতিবেদন করতে ব্যতিক্রমগুলি ব্যবহার করবেন কিনা তা হিসাবে: আপনি ঠিক বলেছেন - এটি কীভাবে ব্যবহৃত হচ্ছে তার উপর নির্ভর করে একই অপারেশন ব্যতিক্রম হিসাবে যোগ্য হতে পারে।

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

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


9

স্ট্যান্ড :: বিটসেট স্ট্রিং-ভিত্তিক কনস্ট্রাক্টর কেবল সি ++ 11 সাল থেকেই বিদ্যমান, সুতরাং এটি ব্যতিক্রমগুলি মাথায় রেখে ব্যবহারের নকশা করা উচিত ছিল। অন্যদিকে আমার কাছে লোকেরা জানিয়েছিল যে লজিক_অরররটি মূলত ব্যবহার করা উচিত নয়।

আপনি এটি বিশ্বাস করতে পারেন না, তবে, ভাল, বিভিন্ন সি ++ কোডার একমত নন। এজন্য এফএকিউ এক জিনিস বলে তবে স্ট্যান্ডার্ড লাইব্রেরি একমত হয় না।

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

স্ট্যান্ডার্ড লাইব্রেরিটি এই তত্ত্বটি গ্রহণ করে যে কোডরটিকে ত্রুটিটি ধরার এবং সম্ভাব্য হ্যান্ডেল করার ক্ষমতা দেওয়ার পরে ডিবাজিবিলিটি আরও গুরুত্বপূর্ণ।

ব্যতিক্রমী হতে পারে, হতে পারে না। ফাংশনটি নিজেই সাধারণত স্পষ্টভাবে জানতে পারে না, কোন ধরণের প্রসঙ্গে এটি বলা হচ্ছে এটির কোনও ধারণা নেই।

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

তবে এটির নিজস্ব সমস্যা রয়েছে। যদি কোনও ক্রিয়াকলাপ থেকে ত্রুটিযুক্ত অবস্থা ফিরে আসে তবে আপনি এটি পরীক্ষা করতে মনে করতে পারেন না এবং ত্রুটিটি নিঃশব্দে কেটে যাবে। এটি কিছু লোককে ব্যর্থতা ত্যাগ করার দিকে পরিচালিত করে যে কোনও ধরণের ত্রুটি অবস্থার জন্য ব্যতিক্রম ছোঁড়ার পক্ষে ব্যতিক্রমী নিয়ম।

সামগ্রিকভাবে, মূল বিষয়টি হ'ল ব্যতিক্রমগুলি কখন ছুঁড়বেন সে সম্পর্কে বিভিন্ন ব্যক্তির বিভিন্ন ধারণা থাকে। আপনি একটি একক সমন্বিত ধারণা খুঁজে পাচ্ছেন না। যদিও কিছু লোকেরা গোপনে দাবী করবে যে এটি বা এটি ব্যতিক্রমগুলি হ্যান্ডেল করার সঠিক উপায়, তত্ত্বের ক্ষেত্রে কোনও একক সম্মত নয় agreed

আপনি ব্যতিক্রম ছুঁড়ে ফেলতে পারেন:

  1. না
  2. সর্বত্র
  3. শুধুমাত্র প্রোগ্রামার ত্রুটিতে
  4. প্রোগ্রামার ত্রুটিতে কখনও নয়
  5. শুধুমাত্র নন-রুটিন (ব্যতিক্রমী) ব্যর্থতার সময়

এবং ইন্টারনেটে এমন কাউকে খুঁজে পান যিনি আপনার সাথে একমত হন। আপনার জন্য কার্যকর এমন স্টাইলটি আপনাকে গ্রহণ করতে হবে।


সম্ভবত এটি লক্ষণীয় যে পরিস্থিতিগুলি সত্যই ব্যতিক্রমী যখন কেবল ব্যতিক্রমগুলি ব্যবহার করার পরামর্শটি ব্যতিক্রমগুলির দক্ষতার সাথে এমন ভাষা সম্পর্কে শেখানো লোকেরা ব্যাপকভাবে প্রচার করে। সি ++ এই ভাষাগুলির মধ্যে একটি নয়।
জুলে

1
@ জুলস - এখন যে (পারফরম্যান্স) অবশ্যই আপনার নিজের জবাবের দাবিদার যেখানে আপনি নিজের দাবির ব্যাক আপ করেন। সি ++ ব্যতিক্রম কর্মক্ষমতা হয় অবশ্যই একটি বিষয়, আরো, হয়তো অন্যত্র কম, কিন্তু চিঠিতে "সি ++ ঐ ভাষায় [কোথায় ব্যতিক্রম মন্দ আছে] এক নয়" অবশ্যই বিতর্ক সাপেক্ষ হতে পারে।
মার্টিন বা

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

1
@ জুলস - এই সংখ্যাগুলির জন্য ধন্যবাদ। (কোনও উত্স?) আমি তাদের বিশ্বাস করতে পারি, কারণ জাভা (এবং সি #) স্ট্যাক ট্রেস ক্যাপচার করা দরকার, যা সম্ভবত এটি ব্যয়বহুল বলে মনে হতে পারে। আমার এখনও মনে হয় আপনার প্রাথমিক প্রতিক্রিয়া কৃপণতাপূর্ণ বিভ্রান্তিমূলক, কারণ এমনকি 50x ধীরগতি আমার পক্ষে বেশ ভারী বলে মনে হয়, esp। সি ++ এর মতো একটি পারফরম্যান্স ওরিয়েন্টেড ভাষায়।
মার্টিন বা

2

আরও অনেক ভাল উত্তর লেখা হয়েছে, আমি কেবল একটি ছোট পয়েন্ট যুক্ত করতে চাই।

Traditionalতিহ্যগত উত্তর, বিশেষত যখন আইএসও সি ++ এফএকিউ লেখা হয়েছিল, সাধারণত "সি ++ ব্যতিক্রম" বনাম "সি-স্টাইল রিটার্ন কোড" তুলনা করে। তৃতীয় বিকল্প, "কিছু ধরণের যৌগিক মান ফেরৎ, যেমন একটি structবা union, বা আজকাল, boost::variantবা (প্রস্তাবিত)std::expected , বিবেচনা করা হয় না।

সি ++ 11 এর আগে "একটি যৌগিক ধরণের রিটার্ন করুন" বিকল্পটি সাধারণত খুব দুর্বল ছিল। কারণ, কোনও পদক্ষেপ শব্দার্থবিজ্ঞান ছিল না সুতরাং কোনও কাঠামোর ভিতরে এবং বাইরে জিনিসগুলি অনুলিপি করা খুব সম্ভবত ব্যয়বহুল ছিল। আপনার কোডটি আরভিওর দিকে স্টাইল করা ভাষার পক্ষে সেই সময়ে অত্যন্ত গুরুত্বপূর্ণ ছিল পারফরম্যান্সে যাতে সেরা পারফরম্যান্স পাওয়া যায়। ব্যতিক্রমগুলি কার্যকরভাবে একটি যৌগিক প্রকার ফেরত দেওয়ার সহজ পদ্ধতির মতো ছিল, অন্যথায় এটি বেশ কঠিন হবে।

আইএমও, সি ++ 11 এর পরে, এই বিকল্পটি "আইডিয়ামের অনুরূপ" একটি বৈষম্যমূলক ইউনিয়ন ফিরিয়ে দেবে " Result<T, E> আজকাল ব্যবহৃত সি ++ কোডে আরও বেশি বেশি পছন্দ করা উচিত। কখনও কখনও এটি ত্রুটিগুলি নির্দেশ করার একটি সহজ এবং আরও সুবিধাজনক স্টাইল। ব্যাতিক্রমের সাথে, এই সম্ভাবনাটি সবসময়ই থাকে যেগুলি আগে ফেলে দেয়নি এমন ফাংশনগুলি হঠাৎ একটি চুল্লীর পরে নিক্ষেপ শুরু করতে পারে এবং প্রোগ্রামাররা সর্বদা এই জাতীয় জিনিস নথিভুক্ত করে না। যখন ত্রুটিটি একটি বৈষম্যমূলক ইউনিয়নের রিটার্ন মান হিসাবে অংশ হিসাবে চিহ্নিত করা হয়, এটি প্রোগ্রামার কেবল ত্রুটি কোডটিকে উপেক্ষা করবে এমন সম্ভাবনাটি হ্রাস করে, যা সি-স্টাইল ত্রুটি পরিচালনার স্বাভাবিক সমালোচনা।

সাধারণত Result<T, E>booচ্ছিক মত বুস্ট ধরণের কাজ করে। আপনি operator boolএটি ব্যবহার করে পরীক্ষা করতে পারেন , যদি এটি মান বা ত্রুটি হয়। এবং তারপরে operator *মানটি অ্যাক্সেস করতে বলুন বা অন্য কোনও "get" ফাংশনটি ব্যবহার করুন। সাধারণত যে অ্যাক্সেসটি চেক করা হয় না, গতির জন্য। তবে আপনি এটি তৈরি করতে পারেন যাতে কোনও ডিবাগ বিল্ডে অ্যাক্সেস চেক হয়ে যায় এবং একটি দৃ as়তা নিশ্চিত করে নিশ্চিত করে যে সেখানে কোনও ত্রুটি নয় আসলে একটি মান রয়েছে। এইভাবে যে কেউ ত্রুটিগুলি সঠিকভাবে যাচাই করে না সে আরও কিছু কুখ্যাত সমস্যার চেয়ে কঠোর দৃsert়তা পাবে।

একটি অতিরিক্ত সুবিধা হ'ল ব্যতিক্রমগুলি ব্যতীত যেখানে এটি ধরা না পড়লে এই স্টাইলটি সহ কিছুটা স্বেচ্ছাসেবক দূরত্ব উড়ে যায়, যখন কোনও ফাংশন কোনও ত্রুটি সংকেত শুরু করে যেখানে এটি আগে হয়নি, আপনি সংকলন করতে পারবেন না যদি না কোডটি হ্যান্ডেল করার জন্য পরিবর্তন করা হয়েছে। এটি সমস্যাগুলিকে আরও জোরে করে তোলে - "অপ্রচলিত ব্যতিক্রম" এর traditionalতিহ্যগত সমস্যাটি রানটাইম ত্রুটির চেয়ে কমপাইল-টাইম ত্রুটির মতো হয়ে যায়।

আমি এই স্টাইলের একটি বড় ভক্ত হয়েছি। সাধারণত, আমি আজকাল এই বা ব্যতিক্রমগুলি ব্যবহার করি। তবে আমি ব্যতিক্রমগুলি বড় সমস্যার মধ্যে সীমাবদ্ধ করার চেষ্টা করি। পার্স ত্রুটির মতো কোনও কিছুর expected<T>জন্য আমি উদাহরণ হিসাবে ফিরে আসার চেষ্টা করি । কিছু অপেক্ষাকৃত ছোটখাটো সমস্যা "স্ট্রিং সংখ্যায় রূপান্তরিত করা যায় নি" এর মতো বিষয়গুলি std::stoiএবং boost::lexical_castযা একটি সি ++ ব্যতিক্রম ছুঁড়েছে তা আজকাল আমার কাছে খুব স্বাদযুক্ত বলে মনে হচ্ছে।


1
std::expectedএখনও একটি অ-গৃহীত প্রস্তাব, তাই না?
মার্টিন বা

আপনি ঠিক বলেছেন, আমার ধারণা এটি এখনও গৃহীত হয়নি। তবে বেশ কয়েকটি ওপেন সোর্স বাস্তবায়ন রয়েছে যার চারপাশে ভাসমান, এবং আমি অনুমান করি যে কয়েকবার আমি নিজের মতো করে নিয়েছি। এটি দুটি বৈকল্পিকের চেয়ে কম জটিল কারণ দুটি মাত্র সম্ভাব্য রাষ্ট্র রয়েছে। মূল নকশার বিবেচনাগুলি হ'ল আপনি কী ঠিক ইন্টারফেসটি চান এবং আপনি এটি আন্দ্রেস্কুর প্রত্যাশিত <T> এর মতো হতে চান যেখানে ত্রুটিযুক্ত বস্তুটি আসলে একটি হিসাবে অনুমিত হয় exception_ptr, বা আপনি কেবল কিছু কাঠামোর ধরণ বা কিছু ব্যবহার করতে চান সে রকমই.
ক্রিস বেক

আন্দ্রে আলেকজান্দ্রেস্কুর আলাপ এখানে রয়েছে: channel9.msdn.com/Shows/Going+Dip/… তিনি কীভাবে এইরকম শ্রেণি তৈরি করবেন এবং আপনার কী বিবেচনা হতে পারে তা বিশদভাবে দেখান।
ক্রিস বেক

প্রস্তাবিত [[nodiscard]] attributeএই ত্রুটি পরিচালনার পদ্ধতির জন্য সহায়ক হবে যেহেতু এটি নিশ্চিত করে যে আপনি দুর্ঘটনাক্রমে ত্রুটির ফলাফলকে কেবল উপেক্ষা করবেন না।
কোডসইনচাউস

- হ্যা আমি এএ এর কথা জানতাম। ডিজাইনটি আনপ্যাক করার পরে আমি বেশ অদ্ভুত পেয়েছি ( except_ptr) আপনাকে অভ্যন্তরীণভাবে একটি ব্যতিক্রম ছোঁড়াতে হয়েছিল। ব্যক্তিগতভাবে আমি মনে করি যে এই জাতীয় কোনও সরঞ্জাম কার্যকর করা উচিত p শুধু একটি মন্তব্য।
মার্টিন বা

1

এটি একটি অত্যন্ত বিষয়গত বিষয়, কারণ এটি ডিজাইনের অংশ। এবং নকশাটি মূলত শিল্প হওয়ায় আমি বিতর্ক না করে এই বিষয়গুলি নিয়ে আলোচনা করতে পছন্দ করি (আমি বলছি না যে আপনি বিতর্ক করছেন)।

আমার জন্য, ব্যতিক্রমী মামলাগুলি দুই প্রকারের - সেগুলি যা সংস্থানসমূহের সাথে লেনদেন করে এবং যেগুলি সমালোচনামূলক অপারেশনগুলির সাথে ডিল করে। কী সমালোচনামূলক বিবেচনা করা যেতে পারে তা হাতের সমস্যা এবং অনেক ক্ষেত্রে প্রোগ্রামারের দৃষ্টিভঙ্গির উপর নির্ভর করে।

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

তারপরে আসে রিসোর্স আপডেট করা। এই বিষয়টি আমার কাছে কমপক্ষে, আবেদনটির সমালোচনামূলক অপারেশনের দিকের সাথে নিবিড়ভাবে সম্পর্কিত closely Employeeকোনও ফাংশন সহ এমন একটি শ্রেণীর কল্পনা করুন UpdateDetails(std::string&)যা প্রদত্ত কমা দ্বারা পৃথক করা স্ট্রিংয়ের উপর ভিত্তি করে বিশদটি সংশোধন করে। মেমরির ব্যর্থতা প্রকাশের অনুরূপ, এই জাতীয় ডোমেনগুলিতে আমার অভিজ্ঞতার অভাবের কারণে এই পরিবর্তনগুলি ঘটতে পারে বলে সদস্যের ভেরিয়েবল ভ্যালুগুলির অ্যাসাইনমেন্টটি কল্পনা করা আমার পক্ষে কঠিন। যাইহোক, UpdateDetailsAndUpdateFile(std::string&)নামের মতো কোনও ফাংশন ব্যর্থ হওয়ার আশা করা যায়। এটাকেই আমি ক্রিটিকাল অপারেশন বলি।

এখন, আপনাকে দেখতে হবে যে তথাকথিত সমালোচনামূলক অপারেশনটির কোনও ব্যতিক্রম ছুঁড়ে ফেলার অনুমতি রয়েছে কিনা। আমি বলতে চাইছি, ডেস্ট্রাক্টরের মতো ফাইলটিও কি শেষ পর্যন্ত আপডেট করা হচ্ছে, বা প্রতিটি আপডেটের পরে এটি কেবল একটি ভৌতিক কল? এমন কোনও ফ্যালব্যাক মেকানিজম রয়েছে যা নিয়মিত অলিখিত বস্তু লেখেন? আমি যা বলছি তা হ'ল, আপনাকে অপারেশনের সমালোচনা মূল্যায়ন করতে হবে।

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

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

আমি অনেক লোককে দেখি যারা মূলত রিটার্নের মানগুলি ব্যাতিক্রমের সাথে প্রতিস্থাপন করে কারণ তারা সি ++ ব্যবহার করে এবং সি নয়, এবং এটি 'ত্রুটি পরিচালনার একটি দুর্দান্ত বিচ্ছেদ' ইত্যাদি দেয় এবং আমাকে 'মিশ্রণ' ভাষা বন্ধ করতে অনুরোধ করে আমি সাধারণত এ থেকে দূরে থাকি এরকম লোকেরা.


1

প্রথমত, অন্যদের বলেছেন, জিনিষ না যে সি স্পষ্ট কাটা ++ এই প্রোগ্রামটিতে কারণ বেশিরভাগ প্রয়োজনীয়তা ও বাধা কিছুটা সি বৈচিত্রময় ++, অন্যান্য ভাষায় চেয়ে ESP। সি # এবং জাভা, এতে "অনুরূপ" ব্যতিক্রম সংক্রান্ত সমস্যা রয়েছে।

আমি std :: স্টোফ উদাহরণে প্রকাশ করব:

স্ট্যান্ড :: স্টোফে একটি ফাঁকা স্ট্রিং পাস করা (অবৈধ_আরগমেন্টটি ফেলে দেবে) কোনও প্রোগ্রামিং ত্রুটি নয়

মৌলিক চুক্তি , যেমন আমি এটা দেখতে, এই ফাংশন এটা চেষ্টা করে যে একটি ভাসা তা এর যুক্তি রূপান্তর করতে, এবং কোন এটি করতে ব্যর্থ হলে একটি ব্যতিক্রম দ্বারা রিপোর্ট করা হয়। উভয় সম্ভাব্য ব্যতিক্রম থেকে উদ্ভূত হয় logic_errorকিন্তু প্রোগ্রামার-ত্রুটির অর্থে না কিন্তু "ইনপুট না, কখনও, একটি float রূপান্তরিত যাবে না" অর্থে।

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

পার্শ্ব নোট: এই দর্শন, একটি runtime_error পারে কিছু হিসাবে দেখা পারে যা কোনও ফাংশনকে একই ইনপুট দেয়, তাত্ত্বিকভাবে বিভিন্ন রানের জন্য সফল হতে পারে। (যেমন একটি ফাইল অপারেশন, ডিবি অ্যাক্সেস ইত্যাদি)

পরবর্তী পার্শ্ব দ্রষ্টব্য: সি ++ রিজেক্স লাইব্রেরি এখানকার ত্রুটিটি অর্জন করতে বেছে নিয়েছেruntime_error যদিও এখানকার মতোই এটি শ্রেণিবদ্ধ করা যেতে পারে এমন ক্ষেত্রে (অবৈধ রেজেক্স প্যাটার্ন)।

এটি কেবল আইএমএইচও দেখায় যে সি ++ তে গ্রুপিং logic_বা runtime_ত্রুটিটি বেশ ফাসিক এবং সাধারণ ক্ষেত্রে (*) আসলেই খুব একটা সহায়তা করে না - যদি আপনাকে নির্দিষ্ট ত্রুটিগুলি পরিচালনা করতে হয় তবে আপনার সম্ভবত দুটিয়ের চেয়ে কম ধরা দরকার।

(*): যে বলতে চাই যে কোড একটি একক টুকরা সামঞ্জস্যপূর্ণ হওয়া উচিত নয় না, কিন্তু কিনা নিক্ষেপ runtime_বা logic_বা custom_somethings সত্যিই যে গুরুত্বপূর্ণ, আমি মনে করি না।


stofএবং উভয় মন্তব্য করতে bitset:

উভয় ফাংশন যুক্তি হিসাবে স্ট্রিং গ্রহণ করে এবং উভয় ক্ষেত্রে এটি হয়:

  • কোন প্রদত্ত স্ট্রিং বৈধ কিনা তা কলকারীর জন্য পরীক্ষা করার জন্য অ-তুচ্ছ নয় (উদাহরণস্বরূপ সবচেয়ে খারাপ ক্ষেত্রে আপনাকে ফাংশনটির যুক্তিটি প্রতিলিপি করতে হবে; বিটসেটের ক্ষেত্রে, খালি স্ট্রিংটি বৈধ কিনা তা অবিলম্বে পরিষ্কার হয় না, তাই কর্টর সিদ্ধান্ত নিতে দিন)
  • স্ট্রিংটির "পার্স" করার জন্য এটি ইতিমধ্যে ফাংশনের দায়িত্ব, সুতরাং এটি ইতিমধ্যে স্ট্রিংটিকে বৈধতা দিতে হয়েছে, সুতরাং এটি বোঝা যায় যে এটি স্ট্রিংকে "ব্যবহার" করার জন্য একটি ত্রুটি হিসাবে রিপোর্ট করেছে (এবং উভয় ক্ষেত্রেই এটি ব্যতিক্রম) ।

ব্যতিক্রম নিয়ে ঘন ঘন আসে এমন নিয়ম হ'ল "ব্যতিক্রমী পরিস্থিতিতে কেবল ব্যতিক্রমগুলি ব্যবহার করুন"। তবে কোন পরিস্থিতি ব্যতিক্রমী তা কীভাবে জানার জন্য লাইব্রেরির কার্যকারিতা রয়েছে?

এই বিবৃতিটির রয়েছে, আইএমএইচও, দুটি মূল:

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

ত্রুটি পরিচালনা এর স্থানীয় এলাকা : একটি ফাংশন প্রার্থনা করা হয় এবং ব্যতিক্রম অবিলম্বে ধরা এবং প্রক্রিয়া থাকে, তাহলে সেখানে একটি ব্যতিক্রম নিক্ষেপ মধ্যে আছে সামান্য বিন্দু হিসাবে ত্রুটি পরিচালনা আরো বাগাড়ম্বরপূর্ণ হতে হবে সঙ্গেcatch একটি সঙ্গে তুলনায়if

উদাহরণ:

float readOrDefault;
try {
  readOrDefault = stof(...);
} catch(std::exception&) {
  // discard execption, just use default value
  readOrDefault = 3.14f; // 3.14 is the default value if cannot be read
}

এখানে যেখানে মতো কাজগুলির এর TryParseবনাম Parseযখন স্থানীয় কোডের জন্য এক সংস্করণ: খেলার মধ্যে আসা আশা যখন স্থানীয় কোড ধরে নেয় যে এটা আসলে পার্স স্ট্রিং বৈধ বলে, এক সংস্করণ প্রত্যাশিত (অর্থাত অ ব্যতিক্রমী) যে পার্সিং ব্যর্থ হবে।

প্রকৃতপক্ষে, stofকেবল একটি মোড়কের চারপাশে কেবল (হিসাবে সংজ্ঞায়িত) strtof, তাই যদি আপনি ব্যতিক্রম না চান, তবে এটি ব্যবহার করুন।


সুতরাং, আমি কীভাবে সিদ্ধান্ত নেব যে আমার কোনও বিশেষ ফাংশনের জন্য ব্যতিক্রম ব্যবহার করা উচিত বা না?

আইএমএইচও, আপনার দুটি মামলা রয়েছে:

  • "লাইব্রেরি" ফাংশনের মতো (প্রায়শই বিভিন্ন প্রসঙ্গে ব্যবহার করা হয়): আপনি মূলত সিদ্ধান্ত নিতে পারবেন না। সম্ভবত উভয় সংস্করণ সরবরাহ করুন, সম্ভবত এমন একটি যা ত্রুটির খবর দেয় এবং একটি মোড়ক সরবরাহকারী যা প্রত্যাবর্তিত ত্রুটিটিকে ব্যতিক্রমে রূপান্তরিত করে।

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

অবশ্যই এর মধ্যে জায়গাগুলি থাকবে - কেবল যা প্রয়োজন তা ব্যবহার করুন এবং YAGNI মনে রাখবেন।


শেষ কথা, আমি মনে করি আমার জিজ্ঞাসিত প্রশ্নাগুলির বিবৃতি ফিরে পাওয়া উচিত,

কোনও ফাংশন ব্যবহারের ক্ষেত্রে কোডিং ত্রুটি চিহ্নিত করতে থ্রো ব্যবহার করবেন না। প্রক্রিয়াটি একটি ডিবাগারে প্রেরণ করতে বা প্রক্রিয়া ক্রাশ করতে দৃ as়তা বা অন্য প্রক্রিয়া ব্যবহার করুন ...

আমি সমস্ত ত্রুটিগুলির জন্য এটিতে সাবস্ক্রাইব করেছিলাম যা স্পষ্ট ইঙ্গিত দেয় যে কোনও কিছু গুরুতরভাবে গণ্ডগোল হয়েছে বা কলিং কোডটি স্পষ্টভাবে জানেন না যে এটি কী করছে।

তবে কখন উপযুক্ত প্রায়শই উচ্চ অ্যাপ্লিকেশন নির্দিষ্ট হয়, সুতরাং উপরের লাইব্রেরি ডোমেন বনাম অ্যাপ্লিকেশন ডোমেনটি দেখুন।

কলিং পূর্বশর্তগুলি কীভাবে বৈধ করা যায় এবং কীভাবে এই প্রশ্নে এটি ফিরে আসে , তবে আমি এর মধ্যে যাব না, ইতিমধ্যে খুব দীর্ঘ উত্তর দিতে হবে :-)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.