প্রতিটি একক বিনীত পয়েন্টার রক্ষা করা কি যুক্তিসঙ্গত?


65

একটি নতুন কাজে, আমি কোডের মত কোডের জন্য এই জাতীয় কোডের পতাকাঙ্কিত হয়ে যাচ্ছি:

PowerManager::PowerManager(IMsgSender* msgSender)
  : msgSender_(msgSender) { }

void PowerManager::SignalShutdown()
{
    msgSender_->sendMsg("shutdown()");
}

আমাকে বলা হয়েছে যে শেষ পদ্ধতিটি পড়া উচিত:

void PowerManager::SignalShutdown()
{
    if (msgSender_) {
        msgSender_->sendMsg("shutdown()");
    }
}

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

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

কোডিং স্ট্যান্ডার্ডের পক্ষে কি কোনও ফাংশনে ডিপ্রিফারিত প্রতিটি একক পয়েন্টারটি NULLপ্রথমে এমনকি ব্যক্তিগত ডেটা সদস্যদের জন্যও পরীক্ষা করা প্রয়োজন ? (দ্রষ্টব্য: কিছু প্রসঙ্গ দেওয়ার জন্য, আমরা একটি ভোক্তা ইলেকট্রনিক্স ডিভাইস তৈরি করি, এয়ার ট্র্যাফিক কন্ট্রোল সিস্টেম বা অন্য কিছু 'ব্যর্থতার সমান-জনগণের মরা' পণ্য নয়))

সম্পাদনা : উপরের উদাহরণে, msgSender_সহযোগী optionচ্ছিক নয়। যদি এটি কখনও হয় তবে এটি NULLএকটি বাগ নির্দেশ করে। এটি নির্মাণকারীর মধ্যে পাস করার একমাত্র কারণ তাই PowerManagerমক IMsgSenderসাবক্লাস দিয়ে পরীক্ষা করা যেতে পারে ।

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

  1. প্রতিটি একক বিনীত পয়েন্টারের NULLজন্য ম্যান্ডেটিং গার্ডগুলি ওভারকিল, তবে
  2. পরিবর্তে কোনও রেফারেন্স (যদি সম্ভব হয়) বা constপয়েন্টার ব্যবহার করে আপনি পুরো বিতর্ককে একপাশে পদক্ষেপ নিতে পারেন এবং
  3. assertNULLফাংশনের পূর্বশর্ত পূরণ হয়েছে তা যাচাই করার জন্য বিবৃতি রক্ষীদের আরও আলোকিত বিকল্প ।

14
এক মিনিটের জন্য ভাববেন না যে ভুলগুলি জুনিয়র প্রোগ্রামারগুলির ডোমেন। অভিজ্ঞ স্তরের সমস্ত স্তরের 95% বিকাশকারী কিছুক্ষণের মধ্যে একবারে কিছু উপভোগ করেন। বাকি 5% তাদের দাঁত পড়ে আছে।
blrfl

56
যদি আমি এমন কাউকে এমন কোড লিখতে দেখেছি যা শূন্যতার জন্য যাচাই করে এবং নিঃশব্দে ব্যর্থ হয়, তবে আমি ঘটনাস্থলে তাদের বরখাস্ত করতে চাই।
উইনস্টন ইওয়ার্ট

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

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

6
@ রিগ, আমি নিশ্চিত যে নিরব ব্যর্থতার জন্য উপযুক্ত মামলা রয়েছে। তবে যদি কেউ নীরবতা সাধারণ অনুশীলন হিসাবে ব্যর্থ করে দেয় (যদি এমন কোন রাজ্যে কাজ করা হয় যেখানে তা বোঝা যায় না) তবে আমি সত্যিই কোনও প্রকল্পে কাজ করতে চাই না যা তারা কোড
রাখছে

উত্তর:


66

এটি 'চুক্তির' উপর নির্ভর করে:

যদি একটি বৈধ থাকতে PowerManager হবে তবে IMsgSenderকখনই শূন্যতার জন্য যাচাই করবেন না, তাড়াতাড়ি মারা যায়।

অন্যদিকে যদি এটির একটি থাকতে পারে তবে আপনার যতবার ব্যবহার করা হবে ততবারIMsgSender সাধারণ হিসাবে আপনার পরীক্ষা করা উচিত।

জুনিয়র প্রোগ্রামারটির গল্প সম্পর্কে চূড়ান্ত মন্তব্য, সমস্যাটি আসলে পরীক্ষার পদ্ধতির অভাব।


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

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

1
সরল এবং সহজ, এটি প্রশ্নের সঠিক উত্তর।
ম্যাথু আজকিমভ

2
এটি নিকটতম সঠিক উত্তর তবে আমি 'নাল কখনই পরীক্ষা করি না' এর সাথে একমত হতে পারি না, সর্বদা অবৈধ পরামিতিগুলি বিন্দুতে সেটিকে সদস্য ভেরিয়েবলের জন্য বরাদ্দ করা হবে কিনা তা পরীক্ষা করে দেখুন।
জেমস

মন্তব্যের জন্য ধন্যবাদ। কেউ স্পেসিফিকেশনটি না পড়ে এবং যদি সেখানে কোনও বৈধতা থাকতে হবে তখন নাল মান দিয়ে এটি আরম্ভ করা হলে তাড়াতাড়ি ক্রাশ হওয়া ভাল let
এআরনপসস

77

আমি মনে করি কোডটি পড়া উচিত:

PowerManager::PowerManager(IMsgSender* msgSender)
  : msgSender_(msgSender)
{
    assert(msgSender);
}

void PowerManager::SignalShutdown()
{
    assert(msgSender_);
    msgSender_->sendMsg("shutdown()");
}

এটি আসলে NUL রক্ষার চেয়ে ভাল, কারণ এটি এটি খুব স্পষ্ট করে তোলে যে msgSender_NUL হলে ফাংশনটি কখনই ডাকা উচিত নয় । এটিও নিশ্চিত করে যে এটি ঘটেছে কিনা তা আপনি লক্ষ্য করবেন।

আপনার সহকর্মীদের ভাগ করা "জ্ঞান" চুপচাপ এই ত্রুটিটি অনাকাঙ্ক্ষিত ফলাফল সহ উপেক্ষা করবে।

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

এটি সামান্য বিপরীতমুখী, তবে কিছু ভুল হওয়ার সাথে সাথে ক্র্যাশ করা আপনার কোডটিকে আরও দৃ make় করে তোলে। এটি হ'ল কারণ আপনি আসলে সমস্যাগুলি খুঁজে পান এবং খুব স্পষ্ট কারণও পান।


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

17
সম্ভবত আপনি বিল্ডটি আসলে গ্রাহকের কাছে প্রেরণের আগে এটি পরীক্ষা করে দেখেছেন, তবে হ্যাঁ, এটি একটি সম্ভাব্য ঝুঁকি। সমাধানগুলি সহজ তবে: হয় কেবলমাত্র সক্ষম সক্ষম (আপনি যেভাবেই পরীক্ষা করেছেন এটি সংস্করণ) সহ জাহাজ করুন বা এটিকে আপনার নিজের ম্যাক্রো দিয়ে প্রতিস্থাপন করুন যা রিলিজ মোডে লগ, লগ, ব্যাকট্র্যাস, প্রস্থান, ... দাবি করে।
ক্রিস্টফ প্রোভস্ট

7
@ জেমস - 90% ক্ষেত্রে আপনিও ব্যর্থ NULL চেক থেকে পুনরুদ্ধার করতে পারবেন না। তবে এই ক্ষেত্রে কোডটি নিঃশব্দে ব্যর্থ হয়ে যাবে এবং ত্রুটিটি অনেক পরে উপস্থিত হতে পারে - উদাহরণস্বরূপ আপনি ভেবেছিলেন যে আপনি ফাইলটি সংরক্ষণ করেছেন তবে নাল চেক কখনও কখনও আপনাকে বুদ্ধিমান না রেখে ব্যর্থ হয়। এমন পরিস্থিতি থেকে আপনি পুনরুদ্ধার করতে পারবেন না must আপনি যাচাই করতে পারেন যে এগুলি হবে না, তবে আপনি নাসা উপগ্রহ বা পারমাণবিক বিদ্যুৎ কেন্দ্রের কোড না লিখে আপনার বাজেট হবে বলে আমি মনে করি না। আপনার বলার একটি উপায় থাকা দরকার "আমার কী ধারণা হচ্ছে না তা কি চলছে - প্রোগ্রামটি এই অবস্থায় থাকবে বলে মনে করা হচ্ছে না"।
ম্যাকিয়েজ পাইচোটকা

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

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

30

যদি msgSender কখনও না হয় null, আপনার চেকটি কেবলমাত্র নির্মাণকারীকে দেওয়া উচিতnull । ক্লাসে অন্য যে কোনও ইনপুটগুলির ক্ষেত্রে এটিও সত্য - 'মডিউল' - শ্রেণি, ফাংশন ইত্যাদিতে প্রবেশের স্থানে অখণ্ডতা পরীক্ষা করুন class

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

তদ্ব্যতীত - আপনি যদি নিশ্চিত হন যে তর্কটি কখনই বাতিল হতে পারে না, আপনার শ্রেণীর ব্যবহারের উপর নির্ভর করে রেফারেন্সগুলি ব্যবহার করে বিবেচনা করুন। অন্যথায়, কাঁচা পয়েন্টার ব্যবহার করে std::unique_ptrবা std::shared_ptrএর পরিবর্তে বিবেচনা করুন ।


11

না, পয়েন্টারটির জন্য প্রতিটি এবং প্রতিটি পয়েন্টার ডিरेফারেন্স পরীক্ষা করা যুক্তিসঙ্গত নয় NULL

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

যদি আপনার মতো পরিস্থিতির মুখোমুখি হয়ে থাকি তবে আমি দুটি প্রশ্ন জিজ্ঞাসা করতাম:

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

9

এই উদাহরণটি কোনও ইনপুট প্যারামিটার নাল whether কিনা তার চেয়ে অবজেক্টের আজীবন সম্পর্কে আরও বেশি মনে হয় † যেহেতু আপনি উল্লেখ করেছেন যে PowerManagerঅবশ্যই সর্বদা একটি বৈধ থাকতে হবে IMsgSender, পয়েন্টার দিয়ে তর্কটি পাস করার মাধ্যমে (এর ফলে নাল পয়েন্টারের সম্ভাবনা মঞ্জুরি দেয়) আমাকে ডিজাইনের ত্রুটি হিসাবে আঘাত করে ††

এর মতো পরিস্থিতিতে, আমি ইন্টারফেসটি পরিবর্তন করতে পছন্দ করব যাতে কলারের প্রয়োজনীয়তাগুলি ভাষা দ্বারা প্রয়োগ করা হয়:

PowerManager::PowerManager(const IMsgSender& msgSender)
  : msgSender_(msgSender) {}

void PowerManager::SignalShutdown() {
    msgSender_->sendMsg("shutdown()");
}

এটি পুনরায় লেখার জন্য এটির পুরো জীবনকালের জন্য PowerManagerএকটি রেফারেন্স রাখা দরকার IMsgSender। এটি, পরিবর্তে, একটি অন্তর্নিহিত প্রয়োজনীয়তাও প্রতিষ্ঠিত IMsgSenderকরে যা অবশ্যই তার চেয়ে দীর্ঘতর বেঁচে থাকতে পারে PowerManagerএবং ভিতরে কোনও নাল পয়েন্টার চেকিং বা দৃ as়তার প্রয়োজনকে উপেক্ষা করে PowerManager

আপনি স্মার্ট পয়েন্টার (বুস্ট বা সি ++ 11 এর মাধ্যমে) ব্যবহার করে একই জিনিসটি লিখতে পারেন, স্পষ্টভাবে এর IMsgSenderচেয়ে বেশি দিন বাঁচতে বাধ্য করতে PowerManager:

PowerManager::PowerManager(std::shared_ptr<IMsgSender> msgSender) 
  : msgSender_(msgSender) {}

void PowerManager::SignalShutdown() {
    // Here, we own a smart pointer to IMsgSender, so even if the caller
    // destroys the original pointer, we still have a valid copy
    msgSender_->sendMsg("shutdown()");
}

এই পদ্ধতিটিকে অগ্রাধিকার দেওয়া হয় যদি এটি সম্ভব হয় যে IMsgSenderএর জীবদ্দশায় PowerManager's (অর্থাৎ x = new IMsgSender(); p = new PowerManager(*x);) এর চেয়ে বেশি দীর্ঘ হওয়ার নিশ্চয়তা দেওয়া যায় না ।

Poin পয়েন্টারগুলির বিষয়ে: প্রচণ্ড নাল চেক করা কোড পড়তে আরও শক্ত করে তোলে এবং স্থায়িত্বের উন্নতি করে না (এটি স্থায়িত্বের চেহারা উন্নত করে , যা আরও খারাপ)।

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

যেহেতু এর PowerManagerমালিকানা নেই IMsgSender(এটি কেবল কিছু সময়ের জন্য এটি ধার করা), সেই স্মৃতিটি বরাদ্দকরণ বা নষ্ট করার জন্য এটি দায়বদ্ধ নয়। এই কারণটির কারণেই আমি রেফারেন্সটি পছন্দ করি।

†† যেহেতু আপনি এই চাকরিতে নতুন, তাই আমি প্রত্যাশা করি যে আপনি বিদ্যমান কোডটি হ্যাক করছেন। নকশা ত্রুটিযুক্ত দ্বারা, আমি বোঝাতে চাইছি যে ত্রুটি আপনি যে কোডটির সাথে কাজ করছেন সেটিতে রয়েছে। সুতরাং, যে লোকেরা আপনার কোডটি পতাকাঙ্কিত করছে কারণ এটি নাল পয়েন্টারগুলির জন্য পরীক্ষা করছে না তারা সত্যিই কোড লিখনের জন্য পয়েন্টারগুলির জন্য নিজেকে পতাকাঙ্কিত করছে :)


1
কখনও কখনও কাঁচা পয়েন্টার ব্যবহার করে আসলে কিছুই ভুল হয় না। স্ট্যান্ডার্ড: শেয়ার্ড_পিটার কোনও রূপোর বুলেট নয় এবং এটি একটি যুক্তি তালিকায় ব্যবহার করা স্লপি ইঞ্জিনিয়ারিংয়ের নিরাময়, যদিও আমি বুঝতে পারি যে যখনই সম্ভব এটি ব্যবহার করা 'পাট্টা' হিসাবে বিবেচিত হবে। এমনটি মনে হলে জাভা ব্যবহার করুন।
জেমস

2
আমি বলিনি কাঁচা পয়েন্টারগুলি খারাপ! তারা অবশ্যই তাদের জায়গা আছে। যাইহোক, এই হল সি + + + + , রেফারেন্স (এবং ভাগ পয়েন্টার, এখন) একটি কারণ জন্য ভাষা অংশ। এগুলি ব্যবহার করুন, তারা আপনাকে সফল করার কারণ করবে।
শেঠ

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

8

ব্যতিক্রমগুলির মতো, গার্ডের শর্তগুলি কেবল তখনই কার্যকর যদি আপনি জানেন যে ত্রুটি থেকে পুনরুদ্ধার করতে কী করতে হবে বা আপনি যদি আরও অর্থবহ ব্যতিক্রম বার্তা দিতে চান তবে।

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

যে কোনও সময় কোনও ফাংশন বলা হয়, এবং এটি alচ্ছিক আচরণ নয়, এটি উচ্চস্বরে ব্যর্থ হওয়া উচিত, নীরবে নয়।

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


7

অন্যরা যেমন উল্লেখ করেছে, msgSenderএটি বৈধভাবে হতে পারে কি না তার উপর নির্ভর করে NULL। নিম্নলিখিতটি ধরে নেয় যে এটি কখনই শূন্য হওয়া উচিত নয়

void PowerManager::SignalShutdown()
{
    if (!msgSender_)
    {
       throw SignalException("Shut down failed because message sender is not set.");
    }

    msgSender_->sendMsg("shutdown()");
}

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

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

এর মধ্যে যে কোনও একটিই নীরব ব্যর্থতা এড়াতে পারবে:

  1. এই উত্তরের পরামর্শ অনুসারে অ্যাসেসর্টগুলি ব্যবহার করুন তবে নিশ্চিত করুন যে তারা উত্পাদন কোডটিতে চালু আছে। এটি অবশ্যই সমস্যার সৃষ্টি করতে পারে যদি অন্য দৃser় বিশ্বাসগুলি তারা উত্পাদন বন্ধ হয়ে যাবে এই ধারণার সাথে লেখা হয়।

  2. এটি বাতিল হলে একটি ব্যতিক্রম নিক্ষেপ করুন।


5

আমি কনস্ট্রাক্টরের নাল ফাঁদে ফেলার সাথে একমত এরপরে, সদস্যটি শিরোনামে যদি ঘোষিত হয়:

IMsgSender* const msgSender_;

তারপরে সূচনা করার পরে পয়েন্টারটি পরিবর্তন করা যায় না, সুতরাং এটি নির্মাণে যদি ঠিকঠাক হয় তবে এটি এতে থাকা অবজেক্টের আজীবন ঠিক থাকবে। (বস্তুর উল্লেখ করতে হবে না const হতে।)


এটি দুর্দান্ত পরামর্শ, আপনাকে ধন্যবাদ! আসলে খুব ভাল, আমি দুঃখিত যে আমি এটিকে আরও বেশি ভোট দিতে পারব না। এটি উল্লিখিত প্রশ্নের সরাসরি উত্তর নয়, তবে 'দুর্ঘটনাক্রমে' পয়েন্টার হওয়ার কোনও সম্ভাবনা দূর করার পক্ষে এটি দুর্দান্ত উপায় NULL
এভিয়েডফ্লো 15

@ নেদেফ্লো আমি ভেবেছিলাম "আমি অন্য সবার সাথে একমত" এই প্রশ্নের মূল জোয়ার উত্তর দিয়েছিল। চিয়ার্স যদিও! ;-)
গ্রিম দ্য Opiner

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

@ দেবা প্রবাহ লোকেরা এই প্রতিনিধিটির জন্য কেবল কুইস্টিন্সে যান, এখন এটির উত্তর দেওয়া হবে না, কেউ আবার এটি দেখবে না। ;-) আমি কেবল পপ এছিলাম কারণ এটি পয়েন্টার সম্পর্কিত একটি প্রশ্ন ছিল এবং আমি রক্তাক্ত "সর্বদা স্মার্ট পয়েন্টার ব্যবহার করুন সর্বদা" ব্রিগেডের জন্য out
গ্রিম দ্য Opiner

3

এটি আউটরেট বিপজ্জনক!

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

// Pre: vertex should never be null.
void transform_vertex(Vertex* vertex, ...)
{
    // Inserted by my "wise" co-worker.
    if (!vertex)
        return;
    ...
}

আমি একবার এই জাতীয় ফাংশনে পূর্বশর্তের এমন চেকটি একবারে মুছে ফেলার চেষ্টা করেছি এবং assertকী ঘটবে তা দেখার জন্য এটির পরিবর্তে ।

আমার ভয়াবহতার জন্য, আমি কোডবেজে কোডের কয়েক হাজার লাইনের সন্ধান পেয়েছি যা এই ফাংশনটির শূন্যস্থান পার করছে, কিন্তু যেখানে বিকাশকারীরা সম্ভবত বিভ্রান্ত হয়েছিলেন এবং কাজ না করা পর্যন্ত আরও কোড যুক্ত করেছেন।

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

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

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

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

কোডিং স্ট্যান্ডার্ডের পক্ষে কি কোনও ফাংশনে ডিপ্রিফারিত প্রতিটি একক পয়েন্টারটি প্রথমে NUL- এমনকি ব্যক্তিগত ডেটা সদস্যদের জন্যও পরীক্ষা করা প্রয়োজন?

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

assertএখানে যাওয়ার উপায়। পূর্ব শর্তগুলির লঙ্ঘনগুলি যাতে কারও নজরে না যায়, বা অন্যথায় মার্ফির আইন সহজেই লাথি মারতে পারে।


1
"আসক্তি" যাওয়ার উপায় - তবে মনে রাখবেন যে কোনও আধুনিক সিস্টেমে একটি পয়েন্টারের মাধ্যমে প্রতিটি মেমরির অ্যাক্সেসের একটি নাল-পয়েন্টার যুক্ত থাকে যা হার্ডওয়্যারটিতে নির্মিত হয়। সুতরাং "assert (p! = NULL); রিটার্ন * পি;" এমনকি এড্রেসটি বেশিরভাগ অর্থহীন is
gnasher729

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

@ gnasher729 বা আমি এর একটি অংশ ভুল বুঝেছি। এই আধুনিক সিস্টেমগুলি উত্স কোডের কোন রেখায় দৃ the়তা ব্যর্থ হয়েছে যা দেখায়? আমি সাধারণত কল্পনা করতাম যে তারা সেই সময়ে তথ্যটি হারিয়েছে এবং কেবল সেগফল্ট / অ্যাক্সেস লঙ্ঘন প্রদর্শন করতে পারে তবে আমি "আধুনিক" থেকে অনেক দূরে - এখনও আমার বেশিরভাগ বিকাশের জন্য উইন্ডোজ 7-তে অনড়ভাবে।

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

কারণ আপনি অন্যথায় এটি কেন পরীক্ষা করে দেখতেন, তাই আপনি যদি পরীক্ষা না করে এটি ব্যবহার করেন তবে এটি পরে থেকে একটি সতর্কতা দেবে। আপনি যদি নিজের নিজস্ব দাবির মতো ম্যাক্রো ব্যবহার করেন তবে আপনাকে এটিকে এমনভাবে লেখার জন্য কিছুটা চালাক হতে হবে যাতে "মাই_সেটার (পি! = নুল," এটি একটি নাল পয়েন্টার, বোকা! "); * পি = 1;" আপনাকে কোনও সতর্কতা দেয় না
gnasher729

2

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

এটি বলেছিল, কোড কোনও শূন্যতায় নয়, একটি বাস্তুতন্ত্রে বাস করে। নাল-রক্ষিত আচরণটি সি -++ -তে অ-প্রতিমাসূচক এবং আশ্চর্যজনক হবে এবং তাই ক্ষতিকারক হিসাবে বিবেচনা করা উচিত। সংক্ষেপে, কেউ সি ++ কোডটি সেভাবে লেখেন না , তাই এটি করবেন না ! একটি পাল্টা উদাহরণ হিসাবে, যদিও, নোট করুন যে সি এবং সি ++ এ কল করা free()বা deleteকোনও অন NULL-আপ হওয়ার গ্যারান্টিযুক্ত।


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

আরও ভাল, নির্মাতার একটি const IMsgSender&রেফারেন্স গ্রহণ করা উচিত , যা সম্ভবত হতে পারে না NULL


1

আপনাকে নাল ডিফারেন্সগুলি এড়াতে বলা হওয়ার কারণটি হ'ল আপনার কোডটি শক্তিশালী is অনেক আগে জুনিয়র প্রোগ্রামারগুলির উদাহরণ কেবল উদাহরণ। যে কেউ দুর্ঘটনাক্রমে কোডটি ভেঙে ফেলতে পারে এবং একটি শূন্য डीরিফারেন্স ঘটায় - বিশেষত গ্লোবাল এবং ক্লাস গ্লোবালের জন্য। সি এবং সি ++ এ এটি সরাসরি মেমরি পরিচালনার ক্ষমতা সহ দুর্ঘটনাক্রমে আরও বেশি সম্ভব। আপনি অবাক হতে পারেন, তবে এই জাতীয় জিনিসটি প্রায়শই ঘটে। এমনকি খুব জ্ঞানী, খুব অভিজ্ঞ এবং খুব প্রবীণ বিকাশকারী দ্বারা by

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

আপনার সহকর্মীরা দৃ as় ব্যবহারের সাথে সম্মিলিতভাবে আপনাকে যে পদ্ধতির কথা বলছেন তা আমি পছন্দ করি। পরীক্ষার পরিবেশে ক্রাশ যাতে এটি আরও সুস্পষ্ট যে উত্পাদনে নিখুঁতভাবে ঠিক করতে এবং ব্যর্থ করতে সমস্যা রয়েছে more

আপনার প্রচ্ছন্নতা বা শক্তিশালীকরণের মতো একটি শক্তিশালী কোড নির্ভুলকরণ সরঞ্জাম ব্যবহার করা উচিত। এবং আপনার সমস্ত সংকলক সতর্কতাগুলি সম্বোধন করা উচিত।

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


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

লোকেরা ম্যালোক () এর পরে NULL পরীক্ষা করে দেখলে আমি বিরক্ত হই। এটি আমাকে জানিয়েছে যে তারা কীভাবে আধুনিক ওএস মেমরি পরিচালনা করে তা বুঝতে পারে না।
ক্রিস্টফ প্রোভস্ট

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

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

2
আমাকে যুক্ত করতে দাও যে আমি কখনও কোডটিও দেখিনি (লিনাক্স কার্নেলের বাইরে, যেখানে মেমরির বাইরে থাকা বাস্তবসম্মতভাবে সম্ভব) যা সঠিকভাবে মেমরির বাইরে থাকা শর্তটিকে সঠিকভাবে পরিচালনা করবে। আমি যে কোডটি দেখেছি সেগুলির সমস্তই পরে যাইহোক ক্রাশ হবে। যা কিছু সম্পাদিত হয়েছিল তা হ'ল সময় নষ্ট করা, কোডটিকে আসল সমস্যাটি বোঝার এবং আড়াল করা আরও শক্ত করা। নাল ডিসেরফেরেন্সগুলি ডিবাগ করা সহজ (যদি আপনার কাছে একটি মূল ফাইল থাকে)।
ক্রিস্টফ প্রোভস্ট 21

1

একটি ব্যবহার পয়েন্টার একটি পরিবর্তে রেফারেন্স আমাকে বলুন যে msgSenderহয় শুধুমাত্র একটি বিকল্প এবং এখানে নাল চেক সঠিক হতে পারে হবে। কোড স্নিপেট এটি সিদ্ধান্ত নিতে খুব ধীর। হতে পারে এর মধ্যে অন্যান্য উপাদানও PowerManagerমূল্যবান (বা পরীক্ষামূলক) ...

পয়েন্টার এবং রেফারেন্সের মধ্যে নির্বাচন করার সময়, আমি উভয় বিকল্পের পুঙ্খানুপুঙ্খভাবে ওজন করি। যদি আমাকে কোনও সদস্যের জন্য পয়েন্টার ব্যবহার করতে হয় (এমনকি বেসরকারী সদস্যদের জন্যও), if (x)প্রতিবারই আমি সিদ্ধান্তটি বিবেচনা না করে আমাকে গ্রহণ করতে হবে।


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

@ নেভেডফ্লো: ঠিক আছে, আমি স্বীকার করি, এটি শ্রেণীর আকার এবং পয়েন্টার সদস্যদের দৃশ্যমানতার উপর নির্ভর করে (যা উল্লেখ করা যায় না), আমি ডিফেরেন্সিংয়ের আগে যাচাই করি কিনা। যে ক্ষেত্রে ক্লাসটি ছোট এবং সরল এবং পয়েন্টারগুলি ব্যক্তিগত হয়, আমি তা করি না ...
ওল্ফ

0

এটি আপনি কী হতে চান তার উপর নির্ভর করে।

আপনি লিখেছেন যে আপনি "একটি কনজিউমার ইলেক্ট্রনিক্স ডিভাইস" তে কাজ করছেন। পারেন, একরকম, একটি বাগ সেটিং দ্বারা করানো হয় msgSender_থেকে NULL, আপনি চাও

  • ডিভাইসটি SignalShutdownচালিয়ে যাওয়া , এড়িয়ে যাওয়া কিন্তু তার বাকী অপারেশন চালিয়ে যাওয়া, বা
  • ডিভাইসটি ক্র্যাশ করতে, ব্যবহারকারীকে এটি পুনরায় চালু করতে বাধ্য করছে?

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

অবশ্যই, আপনি বিকল্প 1 চয়ন করেন, একটি assert(অন্যদের দ্বারা প্রস্তাবিত হিসাবে) বিকাশের সময় নজরে না থাকাতে এ জাতীয় বাগের ক্রাইপিংয়ের সম্ভাবনা হ্রাস করার পক্ষে গুরুত্বপূর্ণifনাল পাহারা প্রকাশনা ব্যবহারে ব্যর্থতা প্রশমন মাত্র নেই।

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

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