নতুন কোডে প্রায় সর্বত্র সি ++ 17 এর [[নোডিসকার্ড]] ব্যবহার না করার কারণ কী?


70

সি ++ 17 [[nodiscard]]বৈশিষ্ট্যটির সাথে পরিচয় করিয়ে দেয়, যা প্রোগ্রামাররা এমনভাবে ফাংশনগুলি চিহ্নিত করতে সক্ষম করে যে প্রত্যাবর্তিত বস্তুটি কলার দ্বারা বাতিল করা হলে সংকলক একটি সতর্কতা উত্পন্ন করে; একই বৈশিষ্ট্যটি একটি সম্পূর্ণ শ্রেণীর ধরণের যুক্ত করা যেতে পারে।

আমি মূল প্রস্তাবটিতে এই বৈশিষ্ট্যটির অনুপ্রেরণা সম্পর্কে পড়েছি এবং আমি জানি যে সি ++ 20 স্ট্যান্ডার্ড ফাংশনগুলিতে এই বৈশিষ্ট্যটি যুক্ত করবে std::vector::empty, যার নামগুলি প্রত্যাবর্তনের মান সম্পর্কিত কোনও অস্পষ্ট অর্থ প্রকাশ করে না।

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

এবং নিজেই সি ++ এর ডিজাইন নীতিগুলির মধ্যে একটি নয় যে সংকলকটি যতটা সম্ভব ত্রুটিটি ধরা উচিত?

যদি তাই হয় তবে [[nodiscard]]আপনার নিজের, নন-লেগ্যাসি কোডটি প্রায় প্রতিটি একক নন- voidফাংশন এবং প্রায় প্রতিটি একক শ্রেণীর প্রকারে যুক্ত করবেন না কেন?

আমি এটি নিজের কোডে করার চেষ্টা করেছি এবং এটি এতটা মারাত্মক ভার্বোস বাদে জাভাটির মতো অনুভূত হতে শুরু করে fine মনে হবে আরো অনেক কিছু কম্পাইলার করতে প্রাকৃতিক ডিফল্টরূপে বাতিল রিটার্ন মান সম্পর্কে সতর্ক ব্যতীত কয়েক অন্যান্য ক্ষেত্রে জন্য যেখানে আপনি আপনার উদ্দেশ্য চিহ্নিত [*] ।

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

এ জাতীয় যান্ত্রিকরা কেন নতুন সি ++ কোডে অর্থ পাবে না? ভারবোসিটি কি [[nodiscard]]প্রায় সর্বত্র ব্যবহার না করার একমাত্র কারণ ?


[*] তত্ত্ব অনুসারে, আপনার [[maydiscard]]পরিবর্তে কোনও বৈশিষ্ট্যের মতো কিছু থাকতে পারে , যা printfস্ট্যান্ডার্ড-লাইব্রেরি বাস্তবায়নের মতো ফাংশনেও পূর্ববর্তীভাবে যুক্ত করা যেতে পারে ।


22
ঠিক আছে এখানে বেশ কয়েকটি ফাংশন রয়েছে যেখানে রিটার্নের মানটি বুদ্ধিমানভাবে বাদ দেওয়া যেতে পারে। operator =উদাহরণ স্বরূপ. এবং std::map::insert।
— ইমিবিস

2
@ মিমিবিস: সত্য। স্ট্যান্ডার্ড লাইব্রেরি যেমন ফাংশন পূর্ণ। তবে আমার নিজস্ব কোডে এগুলি অত্যন্ত বিরল বলে মনে হয়; আপনি কি মনে করেন এটি লাইব্রেরি কোড বনাম অ্যাপ্লিকেশন কোডের বিষয়?
— খ্রিস্টান হ্যাকেল

9
"... মারাত্মক ক্রিয়াপদ যা এটি জাভার মতো অনুভূত হতে শুরু করে ..." - সি ++ সম্পর্কে একটি প্রশ্নে এটি পড়ার ফলে আমাকে কিছুটা
— দ্বিধায় ফেলেছে

3
@ ক্রিশ্চিয়ানহ্যাকল মন্তব্যগুলি সম্ভবত "ভাষা বশিং" এর সঠিক জায়গা নয় এবং অবশ্যই জাভা অন্যান্য ভাষার তুলনায় ভার্জোজ। তবে শিরোলেখ ফাইল, অ্যাসাইনমেন্ট অপারেটর, অনুলিপি নির্মাণকারী এবং যথাযথ ব্যবহার সি ++ এ যথেষ্ট পরিমাণেconst "সাধারণ" শ্রেণি (বা বরং "সাধারণ পুরাতন ডেটা অবজেক্ট") ফুটিয়ে তুলতে পারে।
— মার্কো 13

2
@ মার্কো 13: আমি একটি মন্তব্যে এতগুলি পয়েন্ট সম্বোধন করতে পারি না। আসুন এটি সংক্ষেপে করা যাক: জাভাতে শিরোনামের ফাইল নেই, যা ফাইলের সংখ্যা হ্রাস করে তবে সংযোজন বাড়ায়; ওটিওএইচ আপনাকে প্রতিটি স্তরের স্তরের শ্রেণিটিকে তার নিজস্ব ফাইলে এবং প্রতিটি ফাংশনকে একটি শ্রেণিতে স্থাপন করতে বাধ্য করে। সি ++ এ, আপনি প্রায়শই কার্যনির্বাহক অপারেটর এবং অনুলিপি নির্মাণকারী নিজেকে প্রয়োগ করেন না; এই ফাংশনগুলি স্ট্যান্ডার্ড-লাইব্রেরি ক্লাসের মতো std::vectorবা এর জন্য আরও প্রাসঙ্গিক std::unique_ptr, যার মধ্যে আপনার ক্লাস সংজ্ঞাতে কেবল আপনার ডেটা সদস্যের প্রয়োজন। আমি উভয় ভাষা নিয়ে কাজ করেছি; জাভা একটি ওকিশ ভাষা, তবে এটি আরও ভার্ভোজ।
— খ্রিস্টান হ্যাকেল

উত্তর:


73

নতুন কোডে যা পুরানো মানগুলির সাথে সামঞ্জস্য করার প্রয়োজন নেই, সেই বৈশিষ্ট্যটি যেখানেই বুদ্ধিমান হয় সেখানে ব্যবহার করুন। তবে সি ++ এর জন্য [[nodiscard]]একটি খারাপ ডিফল্ট তৈরি করে। অাপনি সুপারিশ করুন:

অন্য কয়েকটি ক্ষেত্রে যেখানে আপনি আপনার অভিপ্রায় চিহ্নিত করেছেন সেগুলি বাদ দিয়ে সংকলকরা পূর্বনির্ধারিতভাবে বাতিল করা ফেরতের মানগুলি সম্পর্কে সতর্ক করা আরও স্বাভাবিক মনে হবে।

এটি হঠাৎ প্রচুর সতর্কতা নির্গত করার জন্য বিদ্যমান, সঠিক কোডের কারণ হতে পারে। যদিও এই জাতীয় পরিবর্তনটি প্রযুক্তিগতভাবে পিছনের দিকে সামঞ্জস্যপূর্ণ হিসাবে বিবেচিত হতে পারে যেহেতু যে কোনও বিদ্যমান কোড এখনও সাফল্যের সাথে সংকলিত হয়েছে, এটি বাস্তবে শব্দার্থবিজ্ঞানের বিশাল পরিবর্তন হবে।

একটি খুব বড় কোড বেস সহ একটি বিদ্যমান, পরিপক্ক ভাষার জন্য ডিজাইনের সিদ্ধান্তগুলি সম্পূর্ণ নতুন ভাষার জন্য নকশার সিদ্ধান্তের চেয়ে অবশ্যই আলাদা। এটি যদি একটি নতুন ভাষা হয় তবে ডিফল্টরূপে সতর্কতা বুদ্ধিমানের হতে পারে। উদাহরণস্বরূপ, নিম ভাষার অপরিবর্তিত মানগুলি স্পষ্টভাবে বাতিল করতে হবে - এটি প্রতিটি প্রকাশের বিবৃতি সি ++ এ castালাইয়ের সাথে মোড়কের মতো হবে (void)(...)।

একটি [[nodiscard]]বৈশিষ্ট্য দুটি ক্ষেত্রে সবচেয়ে কার্যকর:

  • কোনও ফাংশনের যদি কোনও নির্দিষ্ট ফলাফল ফেরৎ দেওয়ার বাইরে কোনও প্রভাব না থাকে, অর্থাত্ খাঁটি। ফলাফলটি ব্যবহার না করা হলে, কলটি অবশ্যই অকেজো। অন্যদিকে, ফলাফল বাতিল করা ভুল হবে না।

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

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

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

    নোট করুন যে কোনও ক্ষেত্রে, অনুলিপিটি যেভাবেই তৈরি করতে হবে তাই আরভিওকে অনুলিপিটি ফিরিয়ে দেওয়ার জন্য ধন্যবাদ বিনামূল্যে।

  • সাবলীল ইন্টারফেস বিবেচনা করুন, যেখানে প্রতিটি অপারেশন বস্তুটি ফেরত দেয় যাতে আরও ক্রিয়াকলাপ সম্পাদন করা যায়। সি ++ তে সর্বাধিক সাধারণ উদাহরণ হ'ল স্ট্রিম সন্নিবেশ অপারেটর <<। [[nodiscard]]প্রতিটি <<ওভারলোডের সাথে একটি বৈশিষ্ট্য যুক্ত করা অত্যন্ত জটিল হবে ।

এই উদাহরণগুলি প্রমাণ করে যে ডিফল্টরূপে নোডিসকার্ড সহ "C ++ 17" এর অধীনে সতর্কতা ছাড়াই আইডিয়োমেটিক সি ++ কোড তৈরি করা বেশ ক্লান্তিকর হবে।

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

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


6
আমি এটি উন্নত করেছি, কারণ এতে দরকারী অন্তর্দৃষ্টি রয়েছে। যদিও এটি সত্যই প্রশ্নের উত্তর দিয়েছে কিনা তা এখনও নিশ্চিত নয়। যেমন popবা অশুচি ফাংশনগুলি পুনরায় operator<<আমার কল্পিত [[maydiscard]]গুণাবলী দ্বারা স্পষ্টভাবে চিহ্নিত করা হবে , সুতরাং কোনও সতর্কতা তৈরি করা হবে না। আপনি কি এই বলে যেমন ফাংশন সাধারণত অনেক বেশি সাধারণ চেয়ে আমি বা বিশ্বাস করতে চাই, অনেক সাধারণ মধ্যে বেশি দেখা আমার নিজের codebases তুলনায়? বিদ্যমান কোড সম্পর্কে আপনার প্রথম অনুচ্ছেদটি অবশ্যই সত্য, তবে তবুও আমাকে অবাক করে তোলে যে অন্য কেউ যদি বর্তমানে তাদের সমস্ত নতুন কোডটি পেপার করছে [[nodiscard]]এবং যদি না হয় তবে কেন তা নয়।
— খ্রিস্টান হ্যাকেল

23
@ ক্রিশ্চিয়ানহ্যাকল: সি ++ এর ইতিহাসে এমন একটি সময় ছিল যেখানে মানগুলি কনস্ট হিসাবে ফিরিয়ে দেওয়া ভাল অভ্যাস হিসাবে বিবেচিত হত। আপনি বলতে পারবেন না returns_an_int() = 0, তাহলে কেন returns_a_str() = ""কাজ করা উচিত ? সি ++ 11 দেখিয়েছিল এটি আসলে একটি ভয়ানক ধারণা, কারণ এখন এই সমস্ত কোডটি চলনগুলি নিষিদ্ধ করেছিল কারণ মানগুলি কনস্টেট ছিল। আমি মনে করি যে পাঠটি থেকে সঠিক পদক্ষেপ নেওয়া হ'ল "আপনার কলকারীরা আপনার ফলাফলের সাথে কী করবেন এটি আপনার বিষয় নয়"। ফলাফল উপেক্ষা করা একটি পুরোপুরি বৈধ জিনিস যা কলকারীরা করতে চাইবে এবং যদি না আপনি এটি ভুল (খুব উচ্চ বার) না জানেন তবে আপনার এটিকে অবরুদ্ধ করা উচিত নয়।
— GManNickG

13
empty()নামটি বেশ অস্পষ্ট বলে একটি নোডিসকার্ড চালুও বোধগম্য: is_empty()এটি কোনও প্রিডিটিক clear()নাকি এটি কোনও মিউটর ? আপনি সাধারণত এই জাতীয় কোনও পরিবর্তন প্রত্যাশা করবেন না, সুতরাং কোনও ফেরতের মান সম্পর্কে সতর্কতা প্রোগ্রামারকে কোনও সমস্যার জন্য সতর্ক করতে পারে। একটি পরিষ্কার নাম সহ, এই বৈশিষ্ট্যটি প্রয়োজনীয় হবে না।
— আমন

13
@ ক্রিশ্চিয়ানহ্যাকল: অন্যরা যেমন বলেছে, আমি মনে করি খাঁটি ফাংশনগুলি কখন ব্যবহার করা উচিত example আমি আরও একধাপ এগিয়ে গিয়ে বলব একটি [[pure]]বৈশিষ্ট্য থাকা উচিত, এবং এটি বোঝা উচিত [[nodiscard]]। এই ফলাফলটি কেন বাতিল করা উচিত নয় তা পরিষ্কার । তবে খাঁটি ফাংশন ব্যতীত, আমি অন্য শ্রেণীর ফাংশনগুলির সম্পর্কে ভাবতে পারি না যেগুলির এই আচরণ হওয়া উচিত। এবং বেশিরভাগ ফাংশন খাঁটি হয় না, তাই আমি ডিফল্ট হিসাবে নোডিসকার্ড সঠিক পছন্দ বলে মনে করি না।
— GManNickG

5
@GManNickG: রয়ে চেষ্টা এবং ডিবাগ কোডটি উপেক্ষিত ত্রুটি কোডের করতে ব্যর্থ হয়েছে, আমি দৃঢ়ভাবে ত্রুটি কোডের বেশীরভাগ ডিফল্ট দ্বারা চেক করা প্রয়োজন বিশ্বাস করি।
— মাকিং হাঁস

9

কারণগুলি আমি [[nodiscard]]প্রায় সর্বত্রই চাই না :

  1. (প্রধান :) এই পরিচয় করিয়ে দিতে হবে উপায় আমার হেডার মধ্যে খুব গোলমাল।
  2. (মেজর :) অন্যান্য লোকের কোড সম্পর্কে আমার দৃ strong় অনুমানমূলক ধারণা করা উচিত বলে আমি মনে করি না। আমি আপনাকে যে রিটার্ন মান দেব তা বাতিল করতে চান? ভাল, নিজেকে ছিটকে।
  3. (নাবালক :) আপনি সি ++ 14 এর সাথে বেমানান হওয়ার নিশ্চয়তা দিচ্ছেন

এখন, আপনি যদি এটি ডিফল্ট করে থাকেন তবে আপনি সমস্ত গ্রন্থাগার বিকাশকারীকে তাদের সমস্ত ব্যবহারকারীকে রিটার্ন মানগুলি ত্যাগ করতে বাধ্য করতে বাধ্য করবেন। এটা ভয়াবহ হবে। অথবা আপনি তাদের [[maydiscard]]অসংখ্য কর্মে যুক্ত করতে বাধ্য করেন , এটিও এক ধরণের ভয়ঙ্কর।


0

উদাহরণ হিসাবে: অপারেটর << এর রিটার্ন মান রয়েছে যা কলটির উপর নির্ভর করে হয় একেবারে প্রয়োজনীয় বা একেবারেই অকেজো। (std :: cout << x << y, প্রথমটি প্রয়োজন কারণ এটি প্রবাহটি ফিরিয়ে দেয়, দ্বিতীয়টি কোনও কাজে আসে না)। এখন প্রিন্টফের সাথে তুলনা করুন যেখানে প্রত্যেকে যে রিটার্ন মানটি ত্রুটি যাচাইয়ের জন্য রয়েছে তা ত্যাগ করে, তবে অপারেটর << কোনও ত্রুটি পরীক্ষা করার ক্ষেত্রে নেই তাই এটি প্রথম জায়গায় এটি কার্যকর হতে পারে না। সুতরাং উভয় ক্ষেত্রেই নোডিসকার্ড ক্ষতিকারক হবে।


এটি এমন প্রশ্নের উত্তর দেয় যা জিজ্ঞাসা করা হয়নি, অর্থাৎ " [[nodiscard]]সর্বত্র ব্যবহার না করার কারণ কী ?"
— ক্রিশ্চান হ্যাকেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.