অন্যরা যেমন উল্লেখ করেছে, assert
প্রোগ্রামার ভুলগুলির বিরুদ্ধে প্রতিরক্ষার সর্বশেষ ঘাঁটি যা কখনও না ঘটে। এগুলি স্যানিটি চেক যা আশা করছি আপনার চালানোর সময় বাম এবং ডানটি ব্যর্থ হওয়া উচিত নয়।
এটি স্থিতিশীল রিলিজ বিল্ডগুলি থেকে বাদ দেওয়ার জন্যও ডিজাইন করা হয়েছে , যে কোনও কারণেই বিকাশকারীরা কার্যকর মনে করতে পারেন: নন্দনতত্ব, পারফরম্যান্স, যা তারা চান। এটি কোনও ডিবাগ বিল্ডকে একটি রিলিজ বিল্ড থেকে আলাদা করে দেয় এমন একটি অংশ, এবং সংজ্ঞা অনুসারে একটি রিলিজ বিল্ড এ জাতীয় দাবি থেকে বঞ্চিত হয়। সুতরাং ডিজাইনের একটি বিপর্যয় আছে যদি আপনি অ্যানালজিকাল "রিলিজ বিল্ডটি প্লেস ইন দ্য অ্যাশারেন্সস " রিলিজ করতে চান যা একটি _DEBUG
প্রিপ্রোসেসর সংজ্ঞা এবং কোনও NDEBUG
সংজ্ঞায়িত সহ একটি রিলিজ বিল্ডে চেষ্টা হবে ; এটি আসলে আর মুক্তি নয়।
নকশা এমনকি প্রমিত লাইব্রেরি পর্যন্ত প্রসারিত। অসংখ্য মধ্যে একটি খুব মৌলিক উদাহরণ হিসাবে, এর বাস্তবায়নের অনেকটা std::vector::operator[]
হবে assert
নিশ্চিত করুন যে আপনি সীমার বাইরে ভেক্টর চেক করছি না করতে একটি বৈধতা পরীক্ষা। আপনি যদি রিলিজ বিল্ডে এই জাতীয় চেক সক্ষম করে থাকেন তবে মানক গ্রন্থাগারটি অনেক বেশি কার্য সম্পাদন শুরু করবে start vector
ব্যবহারের একটি মানদণ্ডoperator[]
এবং একটি সরল পুরাতন গতিশীল অ্যারের বিপরীতে অন্তর্ভুক্ত এমন জালিয়াতিগুলির সাথে একটি ফিল ফিল্ড প্রায়শই গতিশীল অ্যারে দেখায় যে আপনি এই ধরনের চেকগুলি অক্ষম না করে যতক্ষণ না তারা প্রায়শই তুচ্ছ উপায় থেকে দূরে প্রভাব সম্পাদন করে। এখানে একটি নাল পয়েন্টার চেক এবং সীমানার বাইরে চেকগুলি আসলে একটি বিশাল ব্যয় হয়ে উঠতে পারে যদি এই ধরণের চেকগুলি স্মার্ট পয়েন্টারটিকে ডিফারেন্স করার বা অ্যারে অ্যাক্সেস করার মতো সহজ সরল কোডের পূর্ববর্তী কোডের প্রতিটি ফ্রেমে কয়েক মিলিয়নবার প্রয়োগ করা হয়।
সুতরাং আপনি সম্ভবত কাজের জন্য একটি আলাদা সরঞ্জাম চাইছেন এবং যেটি রিলিজ বিল্ডগুলি থেকে বাদ দেওয়ার জন্য ডিজাইন করা হয়নি সেগুলি যদি আপনি চান যে রিলিজ বিল্ডগুলি চান যা মূল ক্ষেত্রগুলিতে এই জাতীয়তা পরীক্ষা করে perform লগিং হ'ল ব্যক্তিগতভাবে আমি সবচেয়ে দরকারী। সেক্ষেত্রে, যখন কোনও ব্যবহারকারী কোনও ত্রুটির প্রতিবেদন করে, লগ সংযুক্ত করে জিনিসগুলি অনেক সহজ হয়ে যায় এবং লগের শেষ লাইনটি বাগটি কোথায় ঘটেছিল এবং এটি কী হতে পারে সে সম্পর্কে একটি বড় চিহ্ন দেয়। তারপরে, একটি ডিবাগ বিল্ডে তাদের পদক্ষেপগুলি পুনরায় উত্পাদনের পরে, আমি একইভাবে একটি দৃ failure় ব্যর্থতা পেতে পারি এবং সেই দৃser় ব্যর্থতা আমাকে আমার সময়কে আরও সহজ করার জন্য বিশাল সংকেত দেয়। তবুও যেহেতু লগিং তুলনামূলকভাবে ব্যয়বহুল, তাই জেনেরিক ডেটা স্ট্রাকচারে অ্যারে অ্যাক্সেস না করে তা নিশ্চিত করার মতো চূড়ান্ত নিম্ন-স্তরের স্যানিটি চেক প্রয়োগ করতে আমি এটি ব্যবহার করি না।
তবুও অবশেষে এবং আপনার সাথে কিছুটা চুক্তিতে আমি একটি যুক্তিসঙ্গত কেস দেখতে পেলাম যেখানে আপনি আলফা পরীক্ষার সময় ডিবাগ বিল্ডের অনুরূপ কিছু পরীক্ষককে হস্তান্তর করতে চাইতে পারেন, উদাহরণস্বরূপ, আলফা পরীক্ষার্থীদের একটি ছোট গ্রুপের সাথে, যারা এনডিএতে স্বাক্ষর করেছেন । সেখানে যদি আপনি পরীক্ষার্থীদের একটি সম্পূর্ণ রিলিজ বিল্ড ব্যতীত অন্য কোনও ডিবাগিং তথ্য, ডিবাগ / ডেভেলপমেন্ট বৈশিষ্ট্যগুলির সাথে সংযুক্ত করেন যেমন টেস্টগুলি চালানো যেতে পারে এবং সফ্টওয়্যারটি চালানোর সময় আরও ভার্বোজ আউটপুট যুক্ত করে, তবে এটি আলফা টেস্টিংকে প্রবাহিত করতে পারে। আমি কমপক্ষে কিছু বড় গেম সংস্থাগুলি আলফার জন্য এমন কিছু করতে দেখেছি। তবে এটি আলফা বা অভ্যন্তরীণ পরীক্ষার মতো এমন যেখানে আপনি প্রকৃতপক্ষে পরীক্ষকদের একটি রিলিজ বিল্ড ছাড়া অন্য কিছু দেওয়ার চেষ্টা করছেন। যদি আপনি প্রকৃতপক্ষে কোনও রিলিজ বিল্ড শিপ করার চেষ্টা করছেন তবে সংজ্ঞা অনুসারে এটি হওয়া উচিত নয়_DEBUG
সংজ্ঞায়িত করা বা অন্যথায় এটি "ডিবাগ" এবং "রিলিজ" বিল্ডের মধ্যে পার্থক্যটিকে আসলেই বিভ্রান্ত করে।
মুক্তির আগে এই কোডটি কেন সরানো হয়েছে? চেকগুলি কোনও পারফরম্যান্স ড্রেনের বেশি নয় এবং যদি তারা ব্যর্থ হয় তবে অবশ্যই একটি সমস্যা আছে যা আমি সম্পর্কে আরও সরাসরি ত্রুটির বার্তাটি পছন্দ করি।
উপরে উল্লিখিত হিসাবে, পরীক্ষাগুলি পারফরম্যান্সের দিক থেকে তুচ্ছভাবে প্রয়োজনীয় নয়। অনেকগুলি তুচ্ছ হতে পারে তবে আবার, এমনকি স্ট্যান্ডার্ড লিব তাদের ব্যবহার করে এবং এটি অনেক ক্ষেত্রে অগ্রহণযোগ্য উপায়ে পারফরম্যান্সকে প্রভাবিত করতে পারে যদি, যদি বলা যায়, std::vector
অপেক্ষাকৃত রিলিজ বিল্ড হওয়ার কথা বলে যা এলোমেলোভাবে অ্যাক্সেসের ট্র্যাভারসাল 4 গুণ সময় নিয়েছিল কারণ তার সীমানা যাচাই করে যা কখনই ব্যর্থ হয় না।
একটি প্রাক্তন দলে আমরা আমাদের ম্যাট্রিক্স এবং ভেক্টর গ্রন্থাগারকে নির্দিষ্ট সমালোচনামূলক পথে কিছু দৃser়তা বাদ দিতে হয়েছিল কেবলমাত্র ডিবাগ বিল্ডগুলি দ্রুত চালিত করার জন্য, কারণ এই দাবীগুলি যে পরিমাণে ছিল তার প্রস্থের একটি ক্রম দ্বারা গণিতের ক্রিয়াকলাপকে কমিয়ে দিচ্ছিল because এমনকি আগ্রহের কোডটিতে সন্ধান করার আগে আমাদের 15 মিনিট অপেক্ষা করতে হবে starting আমার সহকর্মীরা আসলে এটিকে সরাতে চেয়েছিলasserts
একদম কারণ তারা দেখতে পেয়েছে যে কেবল এটি করা একটি সম্পূর্ণ পার্থক্য করেছে। পরিবর্তে আমরা সমালোচনামূলক ডিবাগ পাথগুলি এড়াতে কেবল স্থির করেছিলাম। যখন আমরা এই গুরুত্বপূর্ণ পথগুলি সীমানা-পরীক্ষার মধ্য দিয়ে না গিয়ে সরাসরি ভেক্টর / ম্যাট্রিক্স ডেটা ব্যবহার করি, তখন পুরো অপারেশনটি সম্পাদনের জন্য প্রয়োজনীয় সময় (যা কেবল ভেক্টর / ম্যাট্রিক্স গণিতের চেয়ে বেশি অন্তর্ভুক্ত) কয়েক মিনিট থেকে সেকেন্ডে হ্রাস পায়। সুতরাং এটি একটি চূড়ান্ত ক্ষেত্রে তবে অবশ্যই দৃ the়ভাবে দাবিগুলি পারফরম্যান্সের দিক থেকে সর্বদাই তুচ্ছ নয়, এমনকি ঘনিষ্ঠও নয়।
তবে এটি ঠিক asserts
ডিজাইন করা হয়েছে। বোর্ডে যদি তাদের এত বিশাল পারফরম্যান্স প্রভাব না থাকে তবে আমি এটির পক্ষে থাকতে পারি যদি সেগুলি যদি কোনও ডিবাগ বিল্ড বৈশিষ্ট্যর চেয়ে আরও বেশি নকশাকৃত হয় বা আমরা ব্যবহার করতে পারি vector::at
যা এর মধ্যে এমনকি রিলিজ বিল্ডগুলিতেও সীমাবদ্ধতা পরীক্ষা করে এবং সীমানার বাইরে ফেলে দেয় অ্যাক্সেস, যেমন (এখনও একটি বিশাল পারফরম্যান্স হিট সহ) with তবে বর্তমানে আমি তাদের ডিজাইনটিকে অনেক বেশি কার্যকর বলে মনে করি, আমার ক্ষেত্রে তাদের বিরাট পারফরম্যান্সের প্রভাবের ভিত্তিতে, একটি ডিবাগ-বিল্ড-কেবল বৈশিষ্ট্য NDEBUG
হিসাবে সংজ্ঞায়িত করার পরে বাদ দেওয়া হয়। আমি যেসব ক্ষেত্রে কমপক্ষে কাজ করেছি সেগুলির ক্ষেত্রে, এটি প্রথমে ব্যর্থ হওয়া উচিত হবে না এমন স্যানিটি চেকগুলি বাদ দিতে একটি রিলিজ বিল্ডের জন্য বিশাল পার্থক্য তৈরি করে।
vector::at
বনাম vector::operator[]
আমি মনে করি এই দুটি পদ্ধতির পার্থক্য এটির পাশাপাশি বিকল্প হিসাবেও রয়েছে: ব্যতিক্রম। সীমানার বাইরে কোনও ভেক্টর অ্যাক্সেস করার চেষ্টা করার সময় সীমা ছাড়িয়ে অ্যাক্সেস একটি সহজে-পুনরুত্পাদনযোগ্য ত্রুটি তৈরি করতে পারে তা নিশ্চিত করার জন্য vector::operator[]
সাধারণত বাস্তবায়নগুলি assert
। তবে গ্রন্থাগার প্রয়োগকারীরা এই ধারণাটি নিয়ে এটি করেন যে এটি একটি অনুকূলিতকরণের রিলিজ বিল্ডের জন্য কোনও অর্থ ব্যয় করবে না।
ইতিমধ্যে vector::at
প্রদান করা হয় যা সর্বদা সীমার বাইরে চলে না এমনকি রিলিজ বিল্ডগুলিতে ছুঁড়ে ফেলে তবে এটিতে এর একটি কার্যক্ষমতা পেনাল্টি রয়েছে যেখানে আমি প্রায়শই এর vector::operator[]
চেয়ে বেশি কোড ব্যবহার করে দেখি vector::at
। সি ++ এর অনেকগুলি নকশায় "আপনি যা ব্যবহার করেন / যা প্রয়োজন তার জন্য অর্থ প্রদান করুন" ধারণাটি প্রতিধ্বনিত করে এবং প্রচুর লোকেরা প্রায়শই অনুগ্রহ করে operator[]
, যা তারা প্রকাশ না করে এমন ধারণার উপর ভিত্তি করে রিলিজ বিল্ডিংয়ের সীমানা পরীক্ষা করেও বিরক্ত করে না তাদের অনুকূলিতকরণের রিলিজ বিল্ডগুলিতে সীমা পরীক্ষা করার দরকার নেই। হঠাৎ যদি দাবিগুলি রিলিজ বিল্ডগুলিতে সক্ষম হয়, তবে এই দুটির পারফরম্যান্স অভিন্ন হবে এবং ভেক্টরের ব্যবহার সর্বদা গতিশীল অ্যারের চেয়ে ধীর হয়ে যায়। সুতরাং দৃser়বিজ্ঞানের নকশা এবং সুবিধার একটি বিশাল অংশ এই ধারণার উপর ভিত্তি করে যে তারা একটি মুক্তির বিল্ডে মুক্ত হয় free
release_assert
এই উদ্দেশ্যগুলি আবিষ্কার করার পরে এটি আকর্ষণীয়। স্বভাবতই প্রত্যেকের ব্যবহারের ক্ষেত্রে ভিন্নতা থাকতে পারে তবে আমি মনে করি যে আমি release_assert
এটির জন্য কিছু ব্যবহার করব যা যা যাচাই করে এবং এমন একটি সফ্টওয়্যার ক্র্যাশ করে যা একটি লাইন নম্বর এবং ত্রুটি বার্তা প্রকাশ করে এমনকি রিলিজ বিল্ডগুলিতেও।
এটি আমার ক্ষেত্রে এমন কিছু অস্পষ্ট মামলার জন্য যেখানে আমি চাই না যে কোনও সফটওয়্যারটি নিখুঁতভাবে পুনরুদ্ধার করবে যেমনটি যদি কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয়। আমি চাইছি এটি এমনকি মুক্তির ক্ষেত্রেও এটি ক্র্যাশ হয়ে যায় যাতে সফ্টওয়্যারটির এমন কোনও ঘটনার মুখোমুখি হওয়া যখন ব্যবহারকারীকে জানাতে একটি লাইন নম্বর দেওয়া যায়, তবুও প্রোগ্রামার ত্রুটির জন্য স্যানিটি চেকের ক্ষেত্রের মধ্যে, যেমন বাহ্যিক ইনপুট ত্রুটিগুলি নয় ব্যতিক্রম, তবে মুক্তির জন্য ব্যয় নিয়ে চিন্তা না করেই করা যথেষ্ট সস্তা।
আসলে কিছু ক্ষেত্রে রয়েছে যেখানে আমি একটি লাইন নম্বর এবং ত্রুটি বার্তা সহ কৃপণভাবে একটি নিক্ষিপ্ত ব্যতিক্রম থেকে ভালভাবে পুনরুদ্ধার করাকে পছন্দ করব যা একটি রিলিজ রাখতে যথেষ্ট সস্তা হতে পারে। এবং এমন কিছু মামলা রয়েছে যেখানে কোনও ব্যতিক্রম থেকে পুনরুদ্ধার করা অসম্ভব যেমন একটি বিদ্যমান পরিস্থিতি থেকে পুনরুদ্ধার করার চেষ্টা করার সময় একটি ত্রুটি হয়েছিল। সেখানে আমি একটি জন্য উপযুক্ত উপযুক্ত খুঁজে release_assert(!"This should never, ever happen! The software failed to fail!");
পেয়েছিলাম এবং স্বাভাবিকভাবেই এটি ময়লা সস্তা যেহেতু চেকটি প্রথমে একটি ব্যতিক্রমী পথের অভ্যন্তরে সঞ্চালিত হবে এবং সাধারণ সম্পাদনের পথে কোনও ব্যয় হবে না।