আমার কখন সত্যই ব্যবহার করা উচিত?


507

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

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

    প্রতিটি ফাংশন ঘোষণার noexceptপরে আমাকে যুক্ত করার দরকার আছে কিনা তা ভেবে প্রোগ্রামার উত্পাদনশীলতা হ্রাস করবে (এবং সত্যি বলতে গেলে পাছায় ব্যথা হবে)। কোন পরিস্থিতিতে আমার ব্যবহার সম্পর্কে আরও সতর্ক হওয়া উচিত এবং কোন পরিস্থিতিতে আমি নিহিতদের সাথে দূরে সরে যেতে পারি ?noexceptnoexcept(false)

  2. আমি কখন বাস্তবের ব্যবহারের পরে কোনও পারফরম্যান্সের উন্নতি পর্যবেক্ষণের আশা করতে পারি noexcept? বিশেষত, কোডটির একটি উদাহরণ দিন যার জন্য একটি সি ++ সংকলক সংযোজনের পরে আরও ভাল মেশিন কোড উত্পন্ন করতে সক্ষম হয় noexcept

    ব্যক্তিগতভাবে, noexceptকয়েকটি ধরণের অপ্টিমাইজেশন নিরাপদে প্রয়োগ করতে সংকলককে সরবরাহ করা বর্ধিত স্বাধীনতার কারণে আমি যত্নশীল । আধুনিক সংকলকরা কি noexceptএইভাবে সুবিধা গ্রহণ করে ? যদি তা না হয় তবে আমি কি তাদের কাছ থেকে অদূর ভবিষ্যতে এমনটি করার আশা করতে পারি?


40
যে move_if_nothrowকোডগুলি (বা হোয়াটম্যাকালিট) ব্যবহার করে সেগুলি যদি কোনও ননডেসেপ্ট মুভ কর্টর থাকে তবে একটি পারফরম্যান্স উন্নতি দেখতে পাবেন।
আর মার্টিনহো ফার্নান্দেস


5
এটা move_if_noexcept
নিকোস

উত্তর:


180

আমি মনে করি এটির জন্য একটি "সেরা অনুশীলন" উত্তর দেওয়া খুব তাড়াতাড়ি কারণ বাস্তবে এটি ব্যবহারের পর্যাপ্ত সময় হয়নি। যদি এগুলি সরাসরি থ্রোল স্পেসিফায়ারদের বাইরে আসার পরে জানতে চাওয়া হয় তবে উত্তরগুলি এখনকার চেয়ে খুব আলাদা হবে।

noexceptপ্রতিটি ফাংশন ঘোষণার পরে আমাকে সংযুক্ত করার দরকার আছে কিনা তা ভেবে প্রোগ্রামার উত্পাদনশীলতা হ্রাস করবে (এবং সত্যি বলতে গেলে ব্যথা হবে)।

ঠিক আছে, তারপরে এটি ব্যবহার করুন যখন স্পষ্ট যে ফাংশনটি কখনই ছুঁড়ে না ফেলে।

আমি কখন বাস্তবের ব্যবহারের পরে কোনও পারফরম্যান্সের উন্নতি পর্যবেক্ষণের আশা করতে পারি noexcept? [...] ব্যক্তিগতভাবে, noexceptকয়েকটি ধরণের অপ্টিমাইজেশন নিরাপদে প্রয়োগ করতে সংকলককে সরবরাহ করা বর্ধিত স্বাধীনতার কারণে আমি যত্নশীল ।

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

ব্যবহার noexceptবড় চার (কনস্ট্রাকটর, নিয়োগ না destructors হিসাবে তারা ইতিমধ্যে করছি noexcept) সম্ভবত শ্রেষ্ঠ উন্নতি ঘটাতে যেমন হবে noexceptচেক যেমন হিসাবে টেমপ্লেট কোডে 'সাধারণ' হয় stdপাত্রে। উদাহরণস্বরূপ, std::vectorএটি চিহ্নিত না করা থাকলে আপনার শ্রেণির পদক্ষেপ ব্যবহার করবে না noexcept(বা সংকলক অন্যথায় এটি ছাড় করতে পারে)।


6
আমি মনে করি std::terminateকৌশলটি এখনও জিরো-কস্ট মডেলকে মান্য করে। অর্থাৎ শুধু তাই যে মধ্যে নির্দেশাবলীর পরিসীমা noexceptফাংশান কল করার ম্যাপ করা হয় std::terminateযদি throwস্ট্যাকের unwinder পরিবর্তে ব্যবহার করা হয়। তাই আমি সন্দেহ করি যে এটির নিয়মিত ব্যতিক্রম ট্র্যাকিংয়ের আরও বেশি ওভারহেড রয়েছে।
ম্যাথিউ এম।

4
@Klaim এই দেখুন: stackoverflow.com/a/10128180/964135 বাস্তবিক এটা শুধু অ নিক্ষেপ করা হয়েছে, কিন্তু noexceptনিশ্চয়তা করেছেন।
পাব্বি

3
"যদি কোনও noexceptফাংশন নিক্ষেপ করা হয় তখন std::terminateতাকে বলা হয় যা দেখে মনে হয় এটি অল্প পরিমাণে ওভারহেড জড়িত" ... না, এই ধরনের ফাংশনের জন্য ব্যতিক্রম টেবিল তৈরি না করেই এটি প্রয়োগ করা উচিত, যা ব্যতিক্রম প্রেরণকারীকে ধরা উচিত এবং তারপরে জামিন আউট করে।
পোটোসওয়টার

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

26
"ঠিক আছে তবে এটি ব্যবহার করুন যখন স্পষ্ট যে ফাংশনটি কখনও ছোঁড়াবে না" " আমি একমত নই noexceptফাংশনের ইন্টারফেসের অংশ ; আপনার বর্তমান প্রয়োগটি নিক্ষেপ না হওয়ার কারণে এটি যুক্ত করা উচিত নয় । আমি এই প্রশ্নের সঠিক উত্তর সম্পর্কে নিশ্চিত নই, তবে আমি যথেষ্ট আত্মবিশ্বাসী যে আজ আপনার ফাংশনটি আচরণ করার সাথে এর কোনও
নিমো

133

আমি যেমন এই দিনগুলি পুনরাবৃত্তি করে যাচ্ছি: প্রথমে শব্দার্থক

যোগ করা noexcept, noexcept(true)এবং noexcept(false)শব্দার্থবিদ্যা সম্পর্কে প্রথম এবং সর্বাগ্রে। এটি ঘটনাক্রমে সম্ভাব্য কয়েকটি অপটিমাইজেশন শর্ত করে।

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


ঠিক আছে, এখন সম্ভাব্য অনুকূলকরণের দিকে।

সর্বাধিক সুস্পষ্ট অপ্টিমাইজেশনগুলি লাইব্রেরিতে সম্পাদিত হয়। সি ++ 11 এমন অনেকগুলি বৈশিষ্ট্য সরবরাহ করে যা কোনও ফাংশন কিনা তা জানার অনুমতি দেয় noexceptএবং স্ট্যান্ডার্ড লাইব্রেরি বাস্তবায়ন noexceptযদি সম্ভব হয় তবে তারা ব্যবহার করে এমন ব্যবহারকারী-সংজ্ঞায়িত অবজেক্টগুলিতে পরিচালনার পক্ষে এই বৈশিষ্ট্যগুলি ব্যবহার করবে । যেমন মুভ শব্দার্থক

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

এই শব্দার্থবিজ্ঞান দুটি কারণে বেছে নেওয়া হয়েছিল:

  • noexceptনির্ভরতা ইতিমধ্যে এটি ব্যবহার না করেও অবিলম্বে উপকারী (পশ্চাদগম্য সামঞ্জস্য)
  • noexceptতাত্ত্বিকভাবে নিক্ষিপ্ত হতে পারে এমন ফাংশনগুলিকে কল করার ক্ষেত্রে স্পেসিফিকেশনকে অনুমতি দেওয়া হচ্ছে তবে প্রদত্ত যুক্তিগুলির জন্য প্রত্যাশিত নয়

2
সম্ভবত আমি নির্বোধ, তবে আমি এমন একটি ফাংশনটি কল্পনা করব যা কেবলমাত্র ফাংশনকেই অনুরোধ করে noexceptবিশেষ কিছু করার প্রয়োজন হবে না, কারণ কোনও ব্যতিক্রম যা terminateএই স্তরে পৌঁছানোর আগেই ট্রিগার তৈরি করতে পারে । এটি কোনও bad_allocব্যাতিক্রমকে মোকাবেলা এবং প্রচার করা থেকে অনেক বেশি পৃথক ।

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

3
@MatthieuM। উত্তরের জন্য কিছুটা দেরি হলেও তবুও। অযোগ্য চিহ্ন চিহ্নিত ফাংশনগুলি অন্য ক্রিয়াকলাপগুলিকে কল করতে পারে যা নিক্ষেপ করতে পারে, প্রতিশ্রুতি হ'ল এই ফাংশনটি একটি ব্যতিক্রম নির্গত করবে না অর্থাৎ তাদের কেবল ব্যতিক্রমটি নিজেরাই পরিচালনা করতে হবে!
মাননীয়

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

5
@ নেমো: স্ট্যান্ডার্ড লাইব্রেরিতে এটি সম্ভবত একমাত্র, তবে এটি এমন একটি নীতি দেখায় যা অন্য কোথাও পুনরায় ব্যবহার করা যেতে পারে। একটি মুভিং অপারেশন হ'ল একটি অপারেশন যা সাময়িকভাবে কিছু অবস্থাকে "লিম্বো" তে রাখে এবং কেবল যখন এটি হয় তখন noexceptকেউ আত্মবিশ্বাসের সাথে ডেটা টুকরো টুকরো ব্যবহার করে যা পরে অ্যাক্সেস করা যায়। আমি এই ধারণাটি অন্য কোথাও ব্যবহৃত হচ্ছে দেখতে পেলাম, তবে স্ট্যান্ডার্ড লাইব্রেরিটি সি ++ এর চেয়ে কম পাতলা এবং এটি কেবলমাত্র আমার মনে হয় এমন উপাদানগুলির অনুলিপিগুলি অনুকূল করতে ব্যবহার করা হয়।
ম্যাথিউ এম।

77

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

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

আপনি একটি নির্দিষ্ট উদাহরণ চেয়েছিলেন। এই কোডটি বিবেচনা করুন:

void foo(int x) {
    try {
        bar();
        x = 5;
        // Other stuff which doesn't modify x, but might throw
    } catch(...) {
        // Don't modify x
    }

    baz(x); // Or other statement using x
}

এই ফাংশনের জন্য প্রবাহের গ্রাফটি barলেবেলযুক্ত থাকলে আলাদা noexcept(মৃত্যুদণ্ড কার্যকর করার কোনও উপায় নেই barএবং ক্যাচ স্টেটমেন্টের মধ্যে লাফ দেওয়ার উপায় নেই )। হিসাবে লেবেলযুক্ত যখন noexcept, সংকলকটি নিশ্চিত হ'ল বাজ ফাংশনের সময় x এর মান 5 হয় - x = 5 ব্লকটি bar()ক্যাচ স্টেটমেন্টের প্রান্তটি ছাড়াই বাজ (এক্স) ব্লকে "আধিপত্য" করতে বলে।

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

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


3
এটি কি বাস্তবে অনুশীলনে কোনও পার্থক্য তৈরি করে? উদাহরণটি গঠন করা হয়েছে কারণ এর আগে কিছুইx = 5 ফেলতে পারে না। যদি tryব্লকের সেই অংশটি কোনও উদ্দেশ্যে পরিবেশিত হয় তবে যুক্তিটি ধরে রাখতে হবে না।
পোটোসওয়টার

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

সংকলক কীভাবে চিনতে পারে যে কোডটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে? এবং অ্যারে অ্যাক্সেসকে কী ব্যতিক্রম হিসাবে বিবেচনা করা হয়?
টমাস কুবেস

3
@ qub1n যদি সংকলকটি ফাংশনটির শরীর দেখতে পারে তবে এটি স্পষ্টত throwবিবৃতি বা অন্য কিছু newনিক্ষেপ করতে পারে for সংকলক যদি শরীর দেখতে না পারে তবে তা অবশ্যই উপস্থিতি বা অনুপস্থিতির উপর নির্ভর করবে noexcept। সরল অ্যারে অ্যাক্সেস সাধারণত ব্যতিক্রম উত্পন্ন করে না (সি ++ এর সীমানা যাচাই করা নেই) সুতরাং না, অ্যারে অ্যাক্সেসটি কেবল কম্পাইলারকে কোনও ফাংশন ব্যতিক্রম ছুঁড়ে ফেলার কথা ভাবায় না। (
বাহিরের

@ সিডিউউই " এটি অবশ্যই নোকেপসেটের উপস্থিতি বা অনুপস্থিতির উপর নির্ভর করবে " বা throw()প্রাক-নথিবদ্ধ সি ++ এর উপস্থিতি
কৌতূহলী

57

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


4
সংযোজন: এর অর্থ আপনি যদি মুভ কনস্ট্রাক্টরগুলি সংজ্ঞায়িত করেন বা অ্যাসাইনমেন্ট অপারেটরগুলি noexceptতাদের সাথে যুক্ত করেন (যদি প্রযোজ্য হয়)! সুস্পষ্টভাবে সংজ্ঞায়িত সরানো সদস্য ফাংশনগুলি noexceptএগুলি স্বয়ংক্রিয়ভাবে যুক্ত হয়েছে (যদি প্রযোজ্য হয়)।
মুচাহো

33

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

উম, কখনই না? কখনই সময় হয় না? কখনও।

noexceptজন্য কম্পাইলার একই ভাবে কর্মক্ষমতা অপ্টিমাইজেশন constকম্পাইলার কর্মক্ষমতা অপ্টিমাইজেশন জন্য। যে, প্রায় কখনও না।

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

পছন্দসই টেমপ্লেটগুলি move_if_noexceptমুভ কনস্ট্রাক্টরের সাথে সংজ্ঞায়িত করা হয়েছে কিনা তা সনাক্ত করবে noexceptএবং যদি তা না হয় তবে এটির const&পরিবর্তে কোনও পরিবর্তিত হবে &&। এটি করা যদি খুব নিরাপদ হয় তবে এটি সরানোর বলার এক উপায়।

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

সংক্ষেপে: এটি মুভ কনস্ট্রাক্টর এবং অনুরূপ নির্মাণের জন্য ব্যবহার করুন, তবে আপনাকে এটি দিয়ে বাদাম যেতে হবে বলে মনে করবেন না।


13
কঠোরভাবে, move_if_noexceptএকটি অনুলিপি ফেরত দেবে না, এটি কোনও মূল্য-রেফারেন্সের চেয়ে কনস্টের লভালিউ-রেফারেন্সটি ফিরিয়ে দেবে। সাধারণভাবে যা কলকারীকে সরানোর পরিবর্তে একটি অনুলিপি তৈরি করতে বাধ্য করবে, তবে move_if_noexceptঅনুলিপিটি করছে না। অন্যথায়, দুর্দান্ত ব্যাখ্যা।
জোনাথন ওয়াকলি

12
+1 জোনাথন। উদাহরণস্বরূপ, একটি ভেক্টরকে পুনরায় আকার দেওয়া, মুভ কনস্ট্রাক্টর হলে বস্তুগুলি অনুলিপি করার পরিবর্তে সরানো হবে noexcept। যাতে "কখনই" সত্য নয়।
mfontanini

4
আমার অর্থ, সংকলকটি সেই পরিস্থিতিতে আরও ভাল কোড তৈরি করবে gene ওপি একটি উদাহরণ চাইছে যার জন্য সংকলক আরও অনুকূলিত অ্যাপ্লিকেশন তৈরি করতে সক্ষম। এটি কেস বলে মনে হচ্ছে (এটি কোনও সংকলক অপ্টিমাইজেশন না হলেও )।
mfontanini

7
@ এমফোঁটানিনি: সংকলকটি আরও ভাল কোড তৈরি করে কারণ সংকলকটি আলাদা কোডে একটি সংকলন করতে বাধ্য হয় । এটি কেবলমাত্র কাজ করে কারণ std::vectorসংকলককে বিভিন্ন কোড সংকলন করতে বাধ্য করার জন্য লেখা হয়েছিল । এটি সংকলকটি কিছু সনাক্ত করার বিষয়ে নয়; এটি ব্যবহারকারী কোড সম্পর্কে কিছু আবিষ্কার করছে।
নিকল বোলাস

3
বিষয়টি হ'ল, আমি আপনার উত্তরের সূচনাতে উদ্ধৃতিতে "সংকলক অপ্টিমাইজেশন" খুঁজে পাচ্ছি না। @ ক্রিশ্চিয়ানো রাউ যেমন বলেছিলেন, সংকলকটি আরও কার্যকর কোড তৈরি করে, সেই অপ্টিমাইজেশনের উত্স কী তা বিবেচ্য নয়। সব পরে, কম্পাইলার হয় আরও কার্যকর কোড তৈরী, তাই নয় কি? পিএস: আমি কখনই বলিনি যে এটি একটি সংকলক অপ্টিমাইজেশন ছিল, আমি এমনকি "এটি কোনও সংকলক অপ্টিমাইজেশনও নয়" বলেছিলাম।
mfontanini

22

ইন বিয়ারনে এর শব্দ ( C ++ Programming Language, 4 র্থ সংস্করণ , পৃষ্ঠা 366):

যেখানে সমাপ্তি একটি গ্রহণযোগ্য প্রতিক্রিয়া, সেখানে একটি অপ্রকাশিত ব্যতিক্রম তা অর্জন করবে কারণ এটি সমাপ্তির কল () (13.5.2.5) এ পরিণত হয়। এছাড়াও, একটি noexceptনির্দিষ্টকারী (§13.5.1.1) সেই ইচ্ছাটিকে স্পষ্ট করে তুলতে পারে।

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

double compute(double x) noexcept;     {
    string s = "Courtney and Anya";
    vector<double> tmp(10);
    // ...
}

ভেক্টর কনস্ট্রাক্টর এটির দশটি দ্বিগুণের জন্য মেমরি অর্জন করতে এবং একটি নিক্ষেপ করতে ব্যর্থ হতে পারে std::bad_alloc। সেক্ষেত্রে প্রোগ্রামটি সমাপ্ত হয়। এটি বিনা শর্তে শেষ করে std::terminate()(.430.4.1.3)। এটি ডেস্ট্রাক্টরদের কলিং ফাংশন থেকে ডাকে না। এটি বাস্তবায়ন-সংজ্ঞায়িত করা হয়েছে যে throwএবং এর মধ্যে স্কোপ থেকে ডেস্ট্রাক্টরগুলি noexcept(যেমন, গণনাতে () এর জন্য) ডাকে। প্রোগ্রামটি প্রায় শেষ হতে চলেছে, সুতরাং আমাদের কোনও বস্তুর উপর নির্ভর করা উচিত নয়। একটি noexceptনির্দিষ্টকারী যুক্ত করে, আমরা নির্দেশ করি যে আমাদের কোডটি কোনও থ্রো মোকাবেলা করার জন্য লেখা হয়নি।


2
আপনার এই উদ্ধৃতিটির কোনও উত্স আছে?
আন্তন গোলভ

5
@ অ্যান্টন গোলভ "দ্য সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ, চতুর্থ সংস্করণ" পৃষ্ঠা 366
রাস্টি শ্যাকলফোর্ড

এটি আমার কাছে মনে হচ্ছে যেন আমি noexceptপ্রতিবারই যুক্ত করা উচিত , ব্যতীত আমি স্পষ্টভাবে ব্যতিক্রমগুলির যত্ন নিতে চাই। আসুন আসুন আসুন, বেশিরভাগ ব্যতিক্রমগুলি এতটা অসম্ভব এবং / বা এত মারাত্মক যে উদ্ধার করা খুব কম যুক্তিসঙ্গত বা সম্ভব। উদ্ধৃত উদাহরণ হিসাবে উদাহরণস্বরূপ, যদি বরাদ্দ ব্যর্থ হয়, অ্যাপ্লিকেশন খুব কমই সঠিকভাবে কাজ চালিয়ে যেতে সক্ষম হবে।
নিওনিত

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

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

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

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

  1. কোন অবস্থার জন্য নোসেপ্ট ব্যবহার সম্পর্কে আমার আরও যত্নবান হওয়া উচিত এবং কোন পরিস্থিতিতে আমি নিহিত নোটিসপেক্ট (মিথ্যা) দিয়ে দূরে যেতে পারি?

চারটি ক্রিয়াকলাপ রয়েছে যা আপনার মনোনিবেশ করা উচিত কারণ সেগুলি সম্ভবত সবচেয়ে বেশি প্রভাব ফেলবে:

  1. অপারেশন সরান (অ্যাসাইনমেন্ট অপারেটর এবং মুভ কনস্ট্রাক্টরগুলি সরান)
  2. অদলবদল অপারেশন
  3. মেমরি deallocators (অপারেটর মুছুন, অপারেটর মুছুন [])
  4. ডেস্ট্রাক্টর (যদিও এগুলি নিখুঁতভাবে তৈরি করা হয় noexcept(true)যদি না আপনি এগুলি তৈরি করেন noexcept(false))

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

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

  1. আমি কখনই বাস্তবতার বাইরে নোকেপসেট ব্যবহার করার পরে কোনও পারফরম্যান্সের উন্নতি পর্যবেক্ষণের আশা করতে পারি? বিশেষত, কোডটির একটি উদাহরণ দিন যার জন্য একটি সি ++ সংকলক নোটসেপ্ট যুক্ত হওয়ার পরে আরও ভাল মেশিন কোড উত্পন্ন করতে সক্ষম।

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

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

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

আমি স্কট মায়ার্স "কার্যকর আধুনিক সি ++" বইয়েরও পরামর্শ দিচ্ছি, "আইটেম 14: ফাংশনগুলি ঘোষণা করুন যদি তারা ব্যাতীতভাবে ছাড়বে না" তবে আরও পড়ার জন্য।


তবুও জাভা যেমন সি ++ তে ব্যতিক্রমগুলি প্রয়োগ করা হয়েছে, সেখানে আপনি এমন পদ্ধতি চিহ্নিত করেছেন throwsযা noexceptনেতিবাচক পরিবর্তে কী- ওয়ার্ডের সাহায্যে ছুঁড়ে ফেলতে পারে তবে এটি আরও বেশি অর্থবোধ করবে। আমি কেবল কিছু সি ++ ডিজাইনের পছন্দগুলি পেতে পারি না ...
ডক

তারা নাম দিয়েছে noexceptকারণ throwইতিমধ্যে নেওয়া হয়েছিল। সহজভাবে বলতে গেলে প্রায়শই আপনারthrow ব্যবহারের উপায়গুলি ব্যবহার করা যেতে পারে , কেবল তারা এর নকশাকে সজ্জিত করা ছাড়া এটি প্রায় অকেজো হয়ে উঠেছে - ক্ষতিকারকও। তবে আমরা এখন এটির সাথে আটকে আছি যেহেতু এটি অপসারণ করা খুব সামান্য উপকারের সাথে একটি ব্রেকিং পরিবর্তন হতে পারে। noexceptমূলত তাই throw_v2
আনোরজাকেন

কিভাবে throwদরকারী না?
কৌতূহলী

@ কুরিয়াসগুয়াই "থ্রো" নিজেই (ব্যতিক্রম ছোঁড়ার জন্য) দরকারী তবে ব্যতিক্রম নির্দিষ্টকরণকারী হিসাবে "নিক্ষেপ" অবমূল্যায়ন করা হয়েছে এবং সি ++ 17 তে এমনকি সরানো হয়েছে। : কেন ব্যতিক্রম নির্দিষ্টকরী দরকারী নয়, এই প্রশ্ন দেখতে পাবেন stackoverflow.com/questions/88573/...
ফিলিপ Classen

1
@ ফিলিপকলেন throw()ব্যতিক্রম স্পেসিফায়ার একই গ্যারান্টি সরবরাহ করেন নি nothrow?
কৌতূহলী

17

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

আপনি যখন বলেন "আমি জানি [তারা] কখনই নিক্ষেপ করবে না", আপনার অর্থ ফাংশনটির বাস্তবায়ন পরীক্ষা করে আপনি জানেন যে ফাংশনটি নিক্ষেপ করবে না। আমি মনে করি যে পদ্ধতির ভিতরে ভিতরে আছে।

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


এটি এখন পর্যন্ত সেরা উত্তর। আপনি আপনার পদ্ধতির ব্যবহারকারীদের জন্য গ্যারান্টি দিচ্ছেন, এটি বলার আর একটি উপায় যা আপনি চিরকাল আপনার প্রয়োগকে সীমাবদ্ধ করছেন (ব্রেকিং-চেঞ্জ) ans আলোকিত দৃষ্টিকোণ জন্য ধন্যবাদ।
আনোরজাকেন

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