সি ++ থ্রো () স্পেসিফায়ার সি ++ 11 নোটের মধ্যে পার্থক্য


100

সেখানে কোন পার্থক্য আছে কী throw()এবং noexceptরানটাইম এবং কম্পাইল সময় যথাক্রমে পরীক্ষা করা হচ্ছে ছাড়া অন্য?

এই উইকিপিডিয়া সি ++ 11 নিবন্ধটি পরামর্শ দেয় যে সি ++ 03 থ্রো স্পেসিফায়ারদের হ্রাস করা হয়েছে।
কেন তাই, noexceptসংকলন সময়ে সমস্ত কি কভার করতে যথেষ্ট সক্ষম?

[দ্রষ্টব্য: আমি এই প্রশ্ন এবং এই নিবন্ধটি যাচাই করেছিলাম , তবে অবমূল্যায়নের শক্ত কারণ নির্ধারণ করতে পারিনি]]


7
এই Accodring চমৎকার নিবন্ধ এছাড়াও noexceptরানটাইম চেক বহন করতে হতে পারে। তাদের মধ্যে প্রধান পার্থক্য হ'ল ব্রেকিং noexceptকারণগুলি std::terminateভাঙ্গার throwকারণগুলি std::unexpected। এছাড়াও এই ক্ষেত্রে কিছুটা ভিন্ন স্ট্যাক অযৌক্তিক আচরণ।
ফিক্টিক

অন্যদের উপর "রানটাইম" চেক করা কিছু ব্যতিক্রম নির্দিষ্টকরণের সাথে চেক করা "সংকলন সময়" তেমন কিছুই নেই। এটি কেবলমাত্র সি ++ ব্যতিক্রমের নির্দিষ্টকরণের বিরোধীদের দ্বারা তৈরি একটি মিথকথা।
কৌতূহলী

উত্তর:


129

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

noexceptআরও শক্তিশালী throw()বলে বাদে কেবলমাত্র সমস্ত থ্রো স্পেসিফায়ার অপসারণের পরিবর্তে যুক্ত করা হয়েছিল noexceptnoexceptএকটি প্যারামিটার থাকতে পারে যা সংকলন-সময়টি বুলিয়ানকে সমাধান করে। বুলিয়ান যদি সত্য হয়, তবে noexceptলাঠিগুলি। বুলিয়ানটি যদি মিথ্যা হয়, তবে noexceptলাঠিটি আটকে না এবং ফাংশনটি ছুঁড়ে দিতে পারে।

সুতরাং, আপনি এর মতো কিছু করতে পারেন:

struct<typename T>
{
  void CreateOtherClass() { T t{}; }
};

কি CreateOtherClassথ্রো ব্যতিক্রম? এটি হতে পারে, যদি Tএর ডিফল্ট কনস্ট্রাক্টর পারেন। আমরা কীভাবে বলব? এটার মত:

struct<typename T>
{
  void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; }
};

সুতরাং, CreateOtherClass()প্রদত্ত প্রকারের ডিফল্ট কনস্ট্রাক্টর ছুড়ে ফেললে if ছুঁড়ে ফেলবে। এটি ব্যতিক্রম স্পেসিফায়ারগুলির সাথে একটি বড় সমস্যা সমাধান করে: কল স্ট্যাকের প্রচারে তাদের অক্ষমতা।

আপনি এটি দিয়ে এটি করতে পারবেন না throw()


+1 দরকারী উত্তর, যাইহোক আমার জন্য। এখনও এমন একটি উত্তর অনুসন্ধান করছে যা বলছে যে আমি কেন ব্যবহার করতে চাই noexcept। আমি কখনই throw()স্পেসিফার ব্যবহার করি নি , এবং noexceptআসলে কোনও সুবিধা সরবরাহ করে কিনা তা নির্ধারণ করার চেষ্টা করছি (সংকলক পরীক্ষিত ডকুমেন্টেশন ব্যতীত)।
এইচএমজেড

শুধু এই পাওয়া stackoverflow.com/questions/10787766/... ...
hmjd

1
@ নিকলবোলাস সম্মত হন তবে নোসসেপ্ট যদি কোনও গ্যারান্টি হয় তবে সংকলকটি কোনও ফাংশন ধ্বংসকারীকে ফেলে দিতে পারে কিনা তা পরীক্ষা করতে পারে। এইভাবে একটি প্রোগ্রামারকে সতর্ক করতে সক্ষম হচ্ছেন যে কোনও ফাংশনটি অযোগ্য বা না।
অ্যালেক্স

2
@ নিকলবোলাস রানটাইম কলগুলি std::terminate। যা ওয়ে ওয়ার ! কোড রিলিজগুলিতে ছিঁড়ে ফেলতে পারে যা ফাংশন চিহ্নিত রয়েছে noexcept এবং রানটাইম (গ্রাহক সাইটের অর্থ) লঙ্ঘন সনাক্ত হয়েছে। আমি বোঝাতে চেয়েছি যে সংকলকটি এমন কোড তৈরির গ্যারান্টি দেয় যা প্রথম স্থানে ব্যতিক্রম ছুঁড়ে না ফেলে
অ্যালেক্স

2
@ নিকলবোলাস: অন্য একটি পার্থক্য লক্ষ্য করার মতো। যদি কোনও ফাংশন চিহ্নিত করা থাকে throws()তবে যদি কোনও ব্যতিক্রম ছুঁড়ে ফেলা হয় তবে স্ট্যাকটি অবশ্যই সেই ফাংশনের সুযোগ পর্যন্ত অযত্ন করা উচিত (সুতরাং ফাংশনটিতে সমস্ত স্বয়ংক্রিয় ভেরিয়েবলগুলি ধ্বংস হয়ে যায়) যেখানে বিন্দুতে terminate()(মাধ্যমে unexpected()) বলা হয় । যদি কোনও ফাংশন চিহ্নিত করা হয় noexceptতবে যদি কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয় তবে সমাপ্তি বলা হয় (স্ট্যাকের আনওয়াইন্ডিং বাস্তবায়ন সংজ্ঞায়িত বিশদ হয়)।
মার্টিন ইয়র্ক

33

noexcept সংকলনের সময় চেক করা হয়নি।

একটি বাস্তবায়ন কেবলমাত্র একটি অভিব্যক্তিটিকে প্রত্যাখ্যান করবে না কারণ এটি কার্যকর করা হলে এটি ছোঁড়ে বা এমন ব্যতিক্রম ছুঁড়ে দিতে পারে যা ধারণকৃত ফাংশনটি মঞ্জুরি দেয় না।

যখন কোনও ফাংশন যা ঘোষিত হয় noexceptবা throw()একটি ব্যতিক্রম ছুঁড়ে ফেলার চেষ্টা করে তখন কেবলমাত্র terminateতফাতটি হল একটি কল এবং অপর কলগুলি unexpectedএবং ব্যতিক্রম হ্যান্ডলিংয়ের পরবর্তী শৈলীটি কার্যকরভাবে হ্রাস পেয়েছে।


তবে যদি ভার্চুয়াল ফাংশনটিতে throw()/ থাকে noexcept, সময় পরীক্ষা করে পরীক্ষা করুন যে ওভাররাইডারটিও রয়েছে।
কৌতূহলী

2

std::unexpected() গতিশীল ব্যতিক্রম নির্দিষ্টকরণের লঙ্ঘন করা হলে সি ++ রানটাইম দ্বারা ডাকা হয়: একটি ফাংশন থেকে ব্যতিক্রম ছুঁড়ে ফেলা হয় যার ব্যতিক্রম স্পেসিফিকেশন এই ধরণের ব্যতিক্রমকে নিষেধ করে।

std::unexpected() প্রোগ্রাম থেকে সরাসরি কল করা যেতে পারে।

উভয় ক্ষেত্রেই, std::unexpectedবর্তমানে ইনস্টল করা কল করুন std::unexpected_handler। ডিফল্ট std::unexpected_handlerকল std::terminate

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