অনেক বেশি দাবী লেখা সম্ভব?


33

আমি assertবিকাশের সময় কেসগুলি ধরার উপায় হিসাবে সি ++ কোডে চেক লেখার একটি বড় অনুরাগ যা আমার প্রোগ্রামে লজিক বাগগুলির কারণে ঘটতে পারে না। এটি সাধারণভাবে একটি ভাল অনুশীলন।

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

ইমাকস মন্তব্য : যেহেতু ইমাক্স আমার পছন্দের আইডিই, তাই আমার কাছে এটি কিছুটা ধূসর বর্ণনাকারী বিবৃতি দেয় যা তারা সরবরাহ করতে পারে এমন বিশৃঙ্খলার অনুভূতি হ্রাস করতে সহায়তা করে। আমি আমার .emacs ফাইলটিতে যা যুক্ত করব তা এখানে:

; gray out the "assert(...)" wrapper
(add-hook 'c-mode-common-hook
  (lambda () (font-lock-add-keywords nil
    '(("\\<\\(assert\(.*\);\\)" 1 '(:foreground "#444444") t)))))

; gray out the stuff inside parenthesis with a slightly lighter color
(add-hook 'c-mode-common-hook
  (lambda () (font-lock-add-keywords nil
    '(("\\<assert\\(\(.*\);\\)" 1 '(:foreground "#666666") t)))))

3
আমাকে অবশ্যই স্বীকার করতে হবে যে এটি এমন একটি প্রশ্ন যা আমার বার বার বার করে দিয়েছে। এ সম্পর্কে অন্যের মতামত শুনতে আগ্রহী।
ক্যাপ্টেন সেনসেবল

উত্তর:


45

আমি কয়েকশো বাগ দেখেছি যে যদি কেউ আরও দৃser়তা লিখত তবে দ্রুত সমাধান করা যেত , এবং একটিও নয় যা কম লিখে আরও দ্রুত সমাধান করা যেত ।

[সি] পঠনযোগ্যতা এবং রক্ষণাবেক্ষণের দিক থেকে [খুব বেশি দাবী] সম্ভবত একটি খারাপ প্রোগ্রামিং অনুশীলন হতে পারে [?]

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

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


1
ভাল উত্তর. আমি কীভাবে ইম্যাক্সের মাধ্যমে পঠনযোগ্যতা উন্নত করব সে প্রশ্নে আমি একটি বিবরণ যুক্ত করেছি।
অ্যালান টুরিং

2
"এটি আমার অভিজ্ঞতা হয়েছে যে ভাল দাবী লেখেন তারা পাঠযোগ্য কোডও লেখেন" << চমৎকার পয়েন্ট। কোড পঠনযোগ্য তৈরি করা পৃথক প্রোগ্রামার হিসাবে যতটা কৌশল তার যেমন তিনি বা তিনি এবং ব্যবহার করার অনুমতি নেই। আমি দেখেছি ভাল কৌশলগুলি ভুল হাতে অপঠনযোগ্য হয়ে উঠেছে, এবং এমনকি খারাপ কৌশলগুলি যেগুলি সবচেয়ে বেশি বিবেচনা করে তা পুরোপুরি পরিষ্কার হয়ে যায়, এমনকি মার্জিত, সঠিকভাবে বিমূর্ততা এবং মন্তব্য করার সঠিক ব্যবহার দ্বারা by
গ্রেগ জ্যাকসন

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

@ কোডসইনচৌস তাত্ক্ষণিকভাবে, টাইপগুলি বাদ দিয়ে, সমস্যাটি গঠনের ক্ষেত্রে এটি একটি ত্রুটির দিকে ইঙ্গিত করে - অর্থাত্ বাগটি নকশায় ছিল, সুতরাং দাবিগুলি এবং (অন্যান্য) কোডের মধ্যে মিল নেই।
লরেন্স

12

অনেক বেশি দাবী লেখা সম্ভব?

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

রান-টাইম এবং বাইনারি পদচিহ্নগুলি মাথায় রাখুন

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

এতে থাকা ফাংশনের ব্যয়ের তুলনায় আমি একটি দৃ of় মূল্য নির্ধারণ করতে চাই the নীচের দুটি উদাহরণ বিবেচনা করুন।

// Precondition:  queue is not empty
// Invariant:     queue is sorted
template <typename T>
const T&
sorted_queue<T>::max() const noexcept
{
  assert(!this->data_.empty());
  assert(std::is_sorted(std::cbegin(this->data_), std::cend(this->data_)));
  return this->data_.back();
}

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

এখানে অনুরূপ দৃser়তা সহ আরও একটি ফাংশন।

// Requirement:   op : T -> T is monotonic [ie x <= y implies op(x) <= op(y)]
// Invariant:     queue is sorted
// Postcondition: each item x in the queue is replaced by op(x)
template <typename T>
template <typename FuncT>
void
sorted_queue<T>::apply_monotonic_function(FuncT&& op)
{
  assert(std::is_sorted(std::cbegin(this->data_), std::cend(this->data_)));
  std::transform(std::cbegin(this->data_), std::cend(this->data_),
                 std::begin(this->data_), std::forward<FuncT>(op));
  assert(std::is_sorted(std::cbegin(this->data_), std::cend(this->data_)));
}

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

এখন এই উদাহরণ বিবেচনা করুন।

// Precondition:  queue is not empty
// Invariant:     queue is sorted
// Postcondition: last element is removed from queue
template <typename T>
void
sorted_queue<T>::pop_back() noexcept
{
  assert(!this->data_.empty());
  return this->data_.pop_back();
}

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

অবশেষে, "সত্যিই সস্তা" জোর রয়েছে যেগুলি যে ফাংশনটিতে অন্তর্ভুক্ত রয়েছে তার জটিলতায় আধিপত্য বজায় রয়েছে।

// Requirement:   cmp : T x T -> bool is a strict weak ordering
// Precondition:  queue is not empty
// Postcondition: if x is returned, then there is no y in the queue
//                such that cmp(x, y)
template <typename T>
template <typename CmpT>
const T&
sorted_queue<T>::max(CmpT&& cmp) const
{
  assert(!this->data_.empty());
  const auto pos = std::max_element(std::cbegin(this->data_),
                                    std::cend(this->data_),
                                    std::forward<CmpT>(cmp));
  assert(pos != std::cend(this->data_));
  return *pos;
}

এখানে, আমাদের একটি ( এন ) ফাংশনে দুটি (1) জরিমানা রয়েছে । এমনকি রিলিজ বিল্ডগুলিতেও এই ওভারহেডটি রাখা সমস্যা হবে না।

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

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

#define MY_ASSERT_IMPL(COST, CONDITION)                                       \
  (                                                                           \
    ( ((COST) <= (MY_ASSERT_COST_LIMIT)) && !(CONDITION) )                    \
      ? ::my::assertion_failed(__FILE__, __LINE__, __FUNCTION__, # CONDITION) \
      : (void) 0                                                              \
  )

#define MY_ASSERT_LOW(CONDITION)                                              \
  MY_ASSERT_IMPL(MY_ASSERT_COST_LOW, CONDITION)

#define MY_ASSERT_MEDIUM(CONDITION)                                           \
  MY_ASSERT_IMPL(MY_ASSERT_COST_MEDIUM, CONDITION)

#define MY_ASSERT_HIGH(CONDITION)                                             \
  MY_ASSERT_IMPL(MY_ASSERT_COST_HIGH, CONDITION)

#define MY_ASSERT_COST_NONE    0
#define MY_ASSERT_COST_LOW     1
#define MY_ASSERT_COST_MEDIUM  2
#define MY_ASSERT_COST_HIGH    3
#define MY_ASSERT_COST_ALL    10

#ifndef MY_ASSERT_COST_LIMIT
#  define MY_ASSERT_COST_LIMIT MY_ASSERT_COST_MEDIUM
#endif

namespace my
{

  [[noreturn]] extern void
  assertion_failed(const char * filename, int line, const char * function,
                   const char * message) noexcept;

}

আপনি এখন তিনটি ম্যাক্রো ব্যবহার করতে পারেন MY_ASSERT_LOW, MY_ASSERT_MEDIUMএবং MY_ASSERT_HIGHস্ট্যান্ডার্ড লাইব্রেরির পরিবর্তে "এক আকার সবই ফিট করে" assertম্যাক্রোর পরিবর্তে যেগুলি প্রভাবিত হয়, যথাক্রমে প্রভাবিত হয় না এবং তাদের ধারণকৃত কার্যকারিতাটির জটিলতাকে প্রাধান্য দেয় না। আপনি যখন সফ্টওয়্যারটি তৈরি করেন, আপনি প্রাক-প্রসেসরের প্রতীকটিকে MY_ASSERT_COST_LIMITনির্বাহযোগ্যর মধ্যে কী ধরনের যুক্তি তৈরি করতে হবে তা চয়ন করতে প্রাক-সংজ্ঞা দিতে পারেন। ধ্রুবকগুলি MY_ASSERT_COST_NONEএবং MY_ASSERT_COST_ALLকোনও দৃsert় ম্যাক্রোগুলির সাথে সামঞ্জস্য করে না এবং বোঝা যায় যে MY_ASSERT_COST_LIMITসমস্ত মানগুলি যথাক্রমে বন্ধ করতে বা যথাক্রমে মান হিসাবে ব্যবহৃত হবে।

আমরা এখানে অনুমানের উপর নির্ভর করছি যে একটি ভাল সংকলক এর জন্য কোনও কোড উত্পন্ন করবে না

if (false_constant_expression && run_time_expression) { /* ... */ }

এবং রূপান্তর

if (true_constant_expression && run_time_expression) { /* ... */ }

মধ্যে

if (run_time_expression) { /* ... */ }

যা আমি বিশ্বাস করি এটি আজকাল নিরাপদ অনুমান।

আপনি উপরের কোড খামচি সম্পর্কে হন, তাহলে মত কম্পাইলার-নির্দিষ্ট টীকা বিবেচনা __attribute__ ((cold))উপর my::assertion_failedবা __builtin_expect(…, false)উপর !(CONDITION)গৃহীত গবেষকেরা এর ভার হ্রাস করা সম্ভব হবে। রিলিজ বিল্ডসগুলিতে, আপনি ডায়াগনস্টিক বার্তা হারাতে অসুবিধার সময়ে পাদদেশ-মুদ্রণ হ্রাস করার my::assertion_failedমতো কিছু দিয়ে ফাংশন কলটি প্রতিস্থাপনের বিষয়টি বিবেচনা করতে পারেন __builtin_trap

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

এই কোডটি কীভাবে তুলনা করুন

int
positive_difference_1st(const int a, const int b) noexcept
{
  if (!(a > b))
    my::assertion_failed(__FILE__, __LINE__, __FUNCTION__, "!(a > b)");
  return a - b;
}

নিম্নলিখিত সমাবেশে সংকলিত হয়

_ZN4test23positive_difference_1stEii:
.LFB0:
        .cfi_startproc
        cmpl    %esi, %edi
        jle     .L5
        movl    %edi, %eax
        subl    %esi, %eax
        ret
.L5:
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        movl    $.LC0, %ecx
        movl    $_ZZN4test23positive_difference_1stEiiE12__FUNCTION__, %edx
        movl    $50, %esi
        movl    $.LC1, %edi
        call    _ZN2my16assertion_failedEPKciS1_S1_
        .cfi_endproc
.LFE0:

যখন নিম্নলিখিত কোড

int
positive_difference_2nd(const int a, const int b) noexcept
{
  if (__builtin_expect(!(a > b), false))
    __builtin_trap();
  return a - b;
}

এই সমাবেশ দেয়

_ZN4test23positive_difference_2ndEii:
.LFB1:
        .cfi_startproc
        cmpl    %esi, %edi
        jle     .L8
        movl    %edi, %eax
        subl    %esi, %eax
        ret
        .p2align 4,,7
        .p2align 3
.L8:
        ud2
        .cfi_endproc
.LFE1:

যা আমি অনেক বেশি স্বাচ্ছন্দ্য বোধ করি। (উদাহরণ ব্যবহার জিসিসি 5.3.0 সঙ্গে পরীক্ষা করা হয়েছিল -std=c++14, -O3এবং -march=native4.3.3-2 আর্কিটেকচার, x86_64 গনুহ / লিনাক্স পতাকা। উপরে স্নিপেট দেখানো না ঘোষণা হয় test::positive_difference_1stএবং test::positive_difference_2ndযা আমি যোগ __attribute__ ((hot))করতে। my::assertion_failedসঙ্গে ঘোষণা করা হয় __attribute__ ((cold))।)

তাদের উপর নির্ভর করে ফাংশনে পূর্বশর্তগুলি যুক্ত করুন

মনে করুন নির্দিষ্ট চুক্তি সহ আপনার নিম্নলিখিত ফাংশন রয়েছে।

/**
 * @brief
 *         Counts the frequency of a letter in a string.
 *
 * The frequency count is case-insensitive.
 *
 * If `text` does not point to a NUL terminated character array or `letter`
 * is not in the character range `[A-Za-z]`, the behavior is undefined.
 *
 * @param text
 *         text to count the letters in
 *
 * @param letter
 *         letter to count
 *
 * @returns
 *         occurences of `letter` in `text`
 *
 */
std::size_t
count_letters(const char * text, int letter) noexcept;

লেখার বদলে

assert(text != nullptr);
assert((letter >= 'A' && letter <= 'Z') || (letter >= 'a' && letter <= 'z'));
const auto frequency = count_letters(text, letter);

প্রতিটি কল-সাইটে, যুক্তির সংজ্ঞাটি একবারে রাখুন count_letters

std::size_t
count_letters(const char *const text, const int letter) noexcept
{
  assert(text != nullptr);
  assert((letter >= 'A' && letter <= 'Z') || (letter >= 'a' && letter <= 'z'));
  auto frequency = std::size_t {};
  // TODO: Figure this out...
  return frequency;
}

এবং এডো না করে এটিকে কল করুন।

const auto frequency = count_letters(text, letter);

এর নিম্নলিখিত সুবিধা রয়েছে।

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

সুস্পষ্ট অসুবিধাটি হ'ল আপনি ডায়াগনস্টিক বার্তায় কল-সাইটের উত্স অবস্থানটি পাবেন না। আমি বিশ্বাস করি এটি একটি ছোটখাটো সমস্যা। একটি ভাল ডিবাগার আপনাকে সুবিধামত চুক্তি লঙ্ঘনের মূলটি সনাক্ত করতে সক্ষম হতে হবে।

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

bool
good() const noexcept;

এটি পুনরুক্তিকারীকে ডিফারেন্স করা নিরাপদ কিনা তা জানতে সহায়তা করে। (অবশ্যই, বাস্তবে, এটির গ্যারান্টি দেওয়া প্রায় সবসময় সম্ভব যে এটি পুনরুক্তিকারীকে অবজ্ঞা করা নিরাপদ হবে না । তবে আমি বিশ্বাস করি যে আপনি এখনও এই জাতীয় কোনও ফাংশন দিয়ে প্রচুর বাগগুলি ধরতে পারেন)) আমার সমস্ত কোড লিটারের পরিবর্তে যে assert(iter.good())স্টেটমেন্টগুলি দিয়ে পুনরুক্তি ব্যবহার করে , আমি তার পরিবর্তে পুনরুক্তির প্রয়োগের assert(this->good())ক্ষেত্রে প্রথম লাইনের হিসাবে একটি একক রাখব operator*

আপনি যদি আপনার উত্স কোডটিতে পূর্ববর্তী শর্তাদি সম্পর্কে ম্যানুয়ালি জোর দেওয়ার পরিবর্তে মানক গ্রন্থাগারটি ব্যবহার করছেন তবে ডিবাগ বিল্ডগুলিতে তাদের চেকগুলি চালু করুন। তারা আরও বেশি পরিশীলিত চেক করতে পারে যেমন পরীক্ষার যে ধারকটি এখনও ব্যবহার করে তা এখনও বিদ্যমান কিনা তা পরীক্ষা করার জন্য। (আরও তথ্যের জন্য libstdc ++ এবং libc ++ (কাজ চলছে) এর জন্য ডকুমেন্টেশন দেখুন ))

ফ্যাক্টর সাধারণ পরিস্থিতি বাইরে

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

template <typename MatrixT>
auto
cholesky_decompose(MatrixT&& m)
{
  assert(is_square(m) && is_symmetric(m));
  // TODO: Somehow decompose that thing...
}

এটি আরও কার্যকর ত্রুটি বার্তা দেবে।

cholesky.hxx:357: cholesky_decompose: assertion failed: is_symmetric(m)

বলার চেয়ে অনেক বেশি সাহায্য করে

detail/basic_ops.hxx:1289: fast_compare: assertion failed: m(i, j) == m(j, i)

আপনাকে প্রথমে উত্সের কোডটি সন্ধান করতে হবে যেখানে প্রকৃতপক্ষে কী পরীক্ষা করা হয়েছিল তা নির্ধারণ করতে।

আপনার যদি classঅ-তুচ্ছ আক্রমণকারীদের সাথে থাকে, আপনি যখন অভ্যন্তরীণ অবস্থার সাথে গোলমাল করেছেন এবং সময় অনুযায়ী অবজেক্টটিকে কোনও বৈধ অবস্থায় রেখে দিচ্ছেন তা নিশ্চিত করার জন্য এটি সময়ে সময়ে তাদের উপর নির্ভর করা ভাল ধারণা to

এই উদ্দেশ্যে, আমি একটি privateসদস্য ফাংশন সংজ্ঞায়িত করতে দরকারী মনে করি যা আমি প্রচলিতভাবে কল করি class_invaraiants_hold_। মনে করুন আপনি পুনরায় বাস্তবায়ন করছেন std::vector(কারণ আমরা সকলেই জানি এটি যথেষ্ট ভাল নয়)), এটির মতো এটির কার্যকারিতা থাকতে পারে।

template <typename T>
bool
vector<T>::class_invariants_hold_() const noexcept
{
  if (this->size_ > this->capacity_)
    return false;
  if ((this->size_ > 0) && (this->data_ == nullptr))
    return false;
  if ((this->capacity_ == 0) != (this->data_ == nullptr))
    return false;
  return true;
}

এ সম্পর্কে কয়েকটি বিষয় লক্ষ্য করুন।

  • প্রেডিকেট ফাংশনটি নিজেই হয় constএবং noexceptনির্দেশিকা অনুসারে যে দৃ .়বিশ্বাসের পার্শ্ব প্রতিক্রিয়া হবে না। যদি এটি বোধগম্য হয় তবে এটিও ঘোষণা করুন constexpr
  • শিকারী কিছু নিজেই জোর দেয় না। এটি অভ্যন্তরীণ দৃ as়তা হিসাবে ডাকা যেতে বোঝানো হয় , যেমন assert(this->class_invariants_hold_())। এইভাবে, যদি দৃser়সংস্থানগুলি সংকলিত হয়, তবে আমরা নিশ্চিত হতে পারি যে কোনও রান-টাইম ওভারহেড ব্যয় করা হয়নি।
  • ফাংশনের অভ্যন্তরে নিয়ন্ত্রণ প্রবাহটি একটি বৃহত প্রকাশের চেয়ে ifপ্রারম্ভিক returnগুলি সহ একাধিক বক্তব্যগুলিতে বিভক্ত হয় । এটি একটি ডিবাগারে ফাংশনটির মধ্য দিয়ে পদক্ষেপ নেওয়া সহজ করে তোলে এবং যদি দৃ fire়তা জানায় তবে আক্রমণকারীটির কোন অংশটি ভেঙে গেছে।

মূর্খ বিষয়গুলিতে দৃsert়তা দেবেন না

কিছু বিষয় কেবল দৃ to়তার সাথে বোঝায় না।

auto numbers = std::vector<int> {};
numbers.push_back(14);
numbers.push_back(92);
assert(numbers.size() == 2);  // silly
assert(!numbers.empty());     // silly and redundant

এই দাবিগুলি কোডটি এমনকি একটি ছোট্ট আরও পড়তে পঠনযোগ্য বা তর্ক করার পক্ষে সহজ করে না। প্রতিটি সি ++ প্রোগ্রামারকে যথেষ্ট আত্মবিশ্বাসী হওয়া উচিত std::vectorযে উপরের কোডটি কেবল এটির দ্বারা দেখলে ঠিক করা যায় যে এটি নিশ্চিত হয়ে কাজ করে। আমি বলছি না যে আপনার কখনই কোনও ধারক আকারের উপর চাপ দেওয়া উচিত নয়। আপনি যদি কিছু অ-তুচ্ছ নিয়ন্ত্রণ প্রবাহ ব্যবহার করে উপাদানগুলি যোগ বা সরিয়ে থাকেন তবে এ জাতীয় দৃ an়তা কার্যকর হতে পারে। তবে এটি যদি কেবল উপরের-অ-দাবি-দাওয়ার কোডে যা লেখা হয়েছিল কেবল পুনরাবৃত্তি করে, কোনও মূল্য অর্জিত হয় না।

লাইব্রেরির ফাংশনগুলি সঠিকভাবে কাজ করে তা জোর করে বলবেন না।

auto w = widget {};
w.enable_quantum_mode();
assert(w.quantum_mode_enabled());  // probably silly

আপনি যদি গ্রন্থাগারটিকে অল্প বিশ্বাস করেন তবে এর পরিবর্তে অন্য একটি লাইব্রেরি ব্যবহার করা ভাল।

অন্যদিকে, লাইব্রেরির ডকুমেন্টেশন যদি 100% স্পষ্ট না হয় এবং উত্স কোডটি পড়ে আপনি এর চুক্তিগুলি সম্পর্কে আত্মবিশ্বাস অর্জন করেন, তবে "অনুমিত চুক্তি" হিসাবে দৃ to় ধারণা পোষণ করা অনেক অর্থবোধ করে। এটি যদি গ্রন্থাগারের ভবিষ্যতের সংস্করণে ভাঙা হয় তবে আপনি দ্রুত লক্ষ্য করবেন।

auto w = widget {};
// After reading the source code, I have concluded that quantum mode is
// always off by default but this isn't documented anywhere.
assert(!w.quantum_mode_enabled());

এটি নিম্নলিখিত সমাধানের চেয়ে ভাল যা আপনার অনুমানগুলি সঠিক ছিল কিনা তা আপনাকে জানায় না।

auto w = widget {};
if (w.quantum_mode_enabled())
  {
    // I don't think that quantum mode is ever enabled by default but
    // I'm not sure.
    w.disable_quantum_mode();
  }

প্রোগ্রাম লজিক বাস্তবায়নের জন্য দৃ abuse়তা অবলম্বন করবেন না

আপনার অ্যাপ্লিকেশনটি তাত্ক্ষণিকভাবে হত্যার উপযুক্ত এমন বাগগুলি অনাবৃত করার জন্য দৃser় প্রতিবেদনগুলি ব্যবহার করা উচিত । সেগুলি অন্য কোনও শর্ত যাচাই করার জন্য ব্যবহার করা উচিত নয় এমনকি যদি সেই অবস্থার যথাযথ প্রতিক্রিয়াটি অবিলম্বে ত্যাগ করা হয়।

অতএব, এটি লিখুন ...

if (!server_reachable())
  {
    log_message("server not reachable");
    shutdown();
  }

…ঐটার পরিবর্তে.

assert(server_reachable());

অবিশ্বাস্য ইনপুটকে বৈধতা দেওয়ার জন্য কখনও কখনও দৃ use়তা ব্যবহার std::mallocকরবেন না বা যা আপনি করেননি তা পরীক্ষা returnকরুন nullptr। এমনকি যদি আপনি জানেন যে আপনি কখনও দৃ .়তা বন্ধ করবেন না, এমনকি রিলিজ বিল্ডেও, একটি প্রতিবেদন পাঠকের সাথে যোগাযোগ করে যে এটি এমন কিছু যাচাই করে যা প্রোগ্রামটি বাগ-মুক্ত রয়েছে এবং এটির কোনও দৃশ্যমান পার্শ্ব-প্রতিক্রিয়া নেই বলে সর্বদা সত্য cks আপনি যদি যোগাযোগ করতে চান এমন বার্তাটি না হয় তবে একটি বিকল্প ব্যর্থতা হ্যান্ডলিং প্রক্রিয়া যেমন throwএকটি ব্যতিক্রম আইএনএস ব্যবহার করুন । যদি আপনার অনাস্থা পরীক্ষার জন্য ম্যাক্রো মোড়ক দেওয়া আপনার পক্ষে সুবিধাজনক মনে হয় তবে একটি লেখার আগে এগিয়ে যান। কেবল এটিকে "দৃsert়বিশ্বাস", "অনুমান", "প্রয়োজনীয়তা", "নিশ্চিত" বা এর মতো কিছু বলবেন না। এর অভ্যন্তরীণ যুক্তিটি একই মত হতে পারে assert, এটি ব্যতীত অবশ্যই কখনই সংকলিত হয় না।

অধিক তথ্য

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


4
Assertions are great, but ... you will turn them off sooner or later.- আশা করি খুব শীঘ্রই, কোড শিপগুলির আগে যেমন। প্রোগ্রামটিকে উত্পাদনে মরতে প্রয়োজনীয় জিনিসগুলি "আসল" কোডের অংশ হওয়া উচিত, জোর দিয়ে নয়।
blrfl

4

আমি দেখতে পেলাম যে সময়ের সাথে আমি কম দৃ write়তা লিখি কারণ তাদের অনেকের পরিমাণ "সংকলক কাজ করছে" এবং "লাইব্রেরিটি কাজ করছে" to আপনি একবার যা পরীক্ষা করছেন ঠিক তা নিয়ে ভাবতে শুরু করার পরে আমি সন্দেহ করি যে আপনি কম জোড় লিখবেন।

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

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


4
আপনি যখন বলেন তখন আমি আপনার বক্তব্যটি পাই না "এটি সাধারণত ক্লাসের পূর্ব শর্ত যে মেসেজটির মালিকানাধীন বা এটি মারাত্মক ত্রুটি যা এটি ব্যবহারকারীর কাছে ফিরে আসা উচিত। সুতরাং একবার খুব তাড়াতাড়ি একবার পরীক্ষা করে দেখুন, তারপরে এটি ধরে নিন ”" আপনার অনুমানগুলি যাচাই না করার জন্য আপনি কী দাবিগুলি ব্যবহার করছেন?
5gon12eder

4

খুব অল্প সংখ্যক বক্তব্য: শুভকামনা লুকানো অনুমানের সাথে পাল্টে দেওয়া কোডটি পরিবর্তন করে।

অনেকগুলি যুক্তি: পাঠযোগ্যতাজনিত সমস্যা এবং সম্ভাব্য কোডের গন্ধ হতে পারে - ক্লাস, ফাংশন, এপিআই সঠিকভাবে ডিজাইন করা হয়েছে যখন এতে অনেকগুলি অনুমানের বিবৃতি দেওয়া হয়?

এমন কিছু বক্তব্যও থাকতে পারে যা প্রতিটি কার্যক্রমে সংকলক সেটিংসের মতো কিছু সত্যই পরীক্ষা করে না বা পরীক্ষা করে না: /

মিষ্টি জায়গার জন্য লক্ষ্য রাখুন, তবে কম নয় (অন্য কেউ ইতিমধ্যে বলেছিলেন যে "বেশি" বলে দাবি করা কম ক্ষতিকারক বা godশ্বর আমাদের সাহায্য করেন - কিছুই নয়) harmful


3

আপনি যদি বুলিয়ান কনস্ট পদ্ধতিতে কেবলমাত্র একটি উল্লেখ লিখেছিলেন তবে আপনি অবশ্যই নিশ্চিত যে আপনার বুলি কোথাও পরীক্ষার জন্য বুলিয়ান কনস্ট পদ্ধতি ব্যবহার করা হয়েছে তা নিশ্চিত করে নিশ্চিত হয়ে আপনার পার্শ্ব প্রতিক্রিয়া নেই বলে নিশ্চিত হয়ে যেতে পারেন!

এটি পাঠযোগ্যতার থেকে কিছুটা আঁকবে, বিশেষত যেহেতু আমি মনে করি না যে আপনি কোনও ল্যাম্বডা (সি ++ 0x তে) কোনও শ্রেণির সংঘবদ্ধ হতে পারেন, যার অর্থ আপনি ল্যাম্বডাস ব্যবহার করতে পারবেন না

আপনি আমাকে জিজ্ঞাসা করলে ওভারকিল, তবে আমি যদি দু'টি বিষয় থেকে সতর্ক থাকি বলে দাবী করার কারণে আমি যদি একটি নির্দিষ্ট মাত্রার দূষণ দেখা শুরু করি:

  • নিশ্চিত করে নিন যে কোনও প্রতিক্রিয়া ঘটছে না (উপরে বর্ণিত একটি কন্সট্রাক্ট সরবরাহ করেছেন)
  • উন্নয়ন পরীক্ষার সময় কর্মক্ষমতা; এড্রেস সুবিধাটিতে স্তরগুলি (লগিংয়ের মতো) যুক্ত করে এটি সমাধান করা যেতে পারে; যাতে আপনি পারফরম্যান্সের উন্নতি করতে কোনও উন্নয়ন বিল্ড থেকে কিছু সংস্থান অক্ষম করতে পারেন

2
পবিত্র বোকা আপনি "নির্দিষ্ট" শব্দটি এবং এর উত্সগুলি পছন্দ করেন। আমি 8 ব্যবহার গণনা।
কেসি প্যাটন

হ্যাঁ, দুঃখিত, আমি শব্দের উপর অনেক বেশি চক্রের ঝোঁক
রেখেছি

2

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

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

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


যদি আপনার কোডটি প্রতি মিনিটে 15 টি প্রতিবেদন ব্যর্থ হয় তবে আমি মনে করি এর সাথে আরও একটি বড় সমস্যা জড়িত রয়েছে। বাগ-ফ্রি কোডে জোর দেওয়া উচিত নয় এবং এটি তারা করে, আরও ক্ষতি রোধ করতে অ্যাপ্লিকেশনটি মেরে ফেলতে হবে বা কী চলছে তা দেখতে আপনাকে কোনও ডিবাগারে ফেলে দিতে হবে।
5gon12eder

2

আমি তোমার সাথে কাজ করতে চাই! যে কেউ প্রচুর লেখেন assertsতা দুর্দান্ত। "অনেক বেশি" বলে কিছু আছে কিনা তা আমি জানি না। আমার কাছে আরও সাধারণ লোকেরা যারা খুব কম লেখেন এবং শেষ পর্যন্ত মাঝেমধ্যে মারাত্মক ইউবি ইস্যুতে ছড়িয়ে পড়ে যা কেবলমাত্র একটি পূর্ণিমার উপরে প্রদর্শিত হয় যা সহজেই একটি সহজ সরল বার বার পুনরুত্পাদন করা যেতে পারে assert

ব্যর্থ বার্তা

আমি যা ভাবতে পারি তা হ'ল আপনি assertযদি ইতিমধ্যে এটি না করে থাকেন তবে ব্যর্থতার তথ্য এম্বেড করা so

assert(n >= 0 && n < num && "Index is out of bounds.");

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

ক্ষতিকর দিক

অবশ্যই assertপ্রকৃতপক্ষে অপব্যবহার করা যেতে পারে এবং ত্রুটিগুলি প্রবর্তন করতে পারে:

assert(foo() && "Call to foo failed!");

... যদি foo()পার্শ্ব প্রতিক্রিয়াগুলি ট্রিগার করে, তাই আপনার এটি সম্পর্কে খুব সতর্ক হওয়া উচিত, তবে আমি নিশ্চিত যে আপনি ইতিমধ্যে একজন যিনি খুব উদারপন্থী (একজন "অভিজ্ঞ অভিজ্ঞ") দাবী করছেন as আশা করি অনুমানগুলি দৃtions় করার জন্য আপনার যত্নের মনোযোগের মতো আপনার পরীক্ষার পদ্ধতিটিও তত ভাল।

ডিবাগিং গতি

ডিবাগিংয়ের গতি সাধারণত আমাদের অগ্রাধিকার তালিকার নীচে থাকা উচিত, এক সময় আমি একটি কোডবেজে এতটা দৃ as়তার সাথে শেষ করেছিলাম যে ডিবাগের মাধ্যমে ডিবাগ বিল্ডটি চালানো মুক্তির চেয়ে 100 গুণ বেশি ধীর ছিল।

এটি মূলত কারণ আমার এর মতো ক্রিয়াকলাপ ছিল:

vec3f cross_product(const vec3f& lhs, const vec3f& rhs)
{
    return vec3f
    (
        lhs[1] * rhs[2] - lhs[2] * rhs[1],
        lhs[2] * rhs[0] - lhs[0] * rhs[2],
        lhs[0] * rhs[1] - lhs[1] * rhs[0]
    );
}

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

একক দায়িত্বের নীতি

যদিও আমি মনে করি না যে আপনি আরও দৃser়তার সাথে সত্যই ভুল হতে পারেন (কমপক্ষে এটি খুব দূরের, খুব কম লোকের চেয়ে অনেকের পক্ষে ভুল করা আরও ভাল), নিজেরাই দাবি করেছেন যে কোনও সমস্যা নাও হতে পারে তবে এটি একটি ইঙ্গিত দিচ্ছে।

উদাহরণস্বরূপ, যদি আপনার একক ফাংশন কলের কাছে 5 টি মতামত থাকে তবে এটি খুব বেশি কাজ করছে। এর ইন্টারফেসে অনেক পূর্বশর্ত এবং ইনপুট প্যারামিটার থাকতে পারে, উদাহরণস্বরূপ, আমি যে স্বাস্থ্যকর সংখ্যার (যা আমি সাধারণত প্রতিক্রিয়া জানাতে চাই, "আরও বেশি বাহক!") এর সাথে সম্পর্কিত নয় তা বিবেচনা করি তবে এটি হতে পারে একটি সম্ভাব্য লাল পতাকা (বা খুব সম্ভবত না)।


1
ঠিক আছে, তত্ত্বের ক্ষেত্রে "অনেকগুলি" জোর দেওয়া যেতে পারে, যদিও সমস্যাটি প্রকৃতপক্ষে দ্রুত প্রকট হয়ে ওঠে: যদি ফাংশনের মাংসের তুলনায় দৃ the়তা যথেষ্ট সময় নেয়। স্বীকারোক্তিহীন, বন্যের মধ্যে এখনও খুঁজে পেয়েছি মনে করতে পারছি না, যদিও বিপরীত সমস্যাটি প্রচলিত।
উত্সাহকটি

@ উত্সাহক হ্যাঁ, আমি সেই সমালোচক ভেক্টর গণিতের রুটিনগুলিতে সেই মামলার মুখোমুখি হয়েছি। যদিও এটি খুব কম লোকের চেয়ে অনেকের পক্ষে ভুল করা অবশ্যই অনেক ভাল বলে মনে হচ্ছে!

-1

আপনার কোডটিতে চেক যুক্ত করা খুব যুক্তিসঙ্গত। সরল প্রতিস্থাপনের জন্য (সি এবং সি ++ সংকলকটিতে নির্মিত একটি) আমার ব্যবহারের প্যাটার্নটি হ'ল ব্যর্থ দাবী মানে কোডটিতে একটি বাগ রয়েছে যা ঠিক করা দরকার। আমি এটিকে কিছুটা উদারভাবে ব্যাখ্যা করি; যদি আমি কোনও ওয়েব অনুরোধের জন্য একটি স্ট্যাটাস 200 ফিরিয়ে আনার এবং অন্য কেসগুলি পরিচালনা না করে এটির জন্য দাবি করার প্রত্যাশা করি তবে একটি ব্যর্থ দাবী সত্যই আমার কোডটিতে একটি বাগ প্রদর্শন করে , তাই দাবিটি ন্যায়সঙ্গত হয়।

সুতরাং যখন লোকেদের এমন দৃsert়তা বলা হয় যা কেবল কোডটি যা করে তা অতিমাত্রায় প্রযোজ্য তা যাচাই করে তোলে যা একেবারেই সঠিক নয়। এই দাবী তারা কোডটি কী করে বলে মনে করে তা যাচাই করে, এবং দৃsert়তার পুরো বিন্দুটি কোডটিতে কোনও বাগের অনুমানটি সঠিক কিনা তা যাচাই করে। এবং দৃsert়লিপি পাশাপাশি ডকুমেন্টেশন হিসাবে পরিবেশন করতে পারে। যদি আমি ধরে নিই যে একটি লুপ কার্যকর করার পরে i == n এবং কোড থেকে এটি 100% সুস্পষ্ট না হয় তবে "দাবী (i == n)" সহায়ক হবে।

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

আরেকটি উদাহরণ হ'ল এমন পরিস্থিতি যেখানে আমি কিছু হওয়ার আশা করি না, আমার একটি জেনেরিক কাজ রয়েছে, তবে যদি এই জিনিসটি ঘটে থাকে তবে আমি এটি সম্পর্কে জানতে এবং এটি পরীক্ষা করতে চাই। আবার প্রায় দৃ an়তার মতো কিছু, যা বিকাশের সময় আমাকে জানা উচিত। তবে বেশ জোর দেওয়া হয়নি not

অনেকগুলি আসক্তি: যদি কোনও প্রোগ্রামের ব্যবহারকারীর হাতে থাকা আপনার প্রোগ্রামটি ক্র্যাশ করে, তবে আপনার অবশ্যই ভুয়া নেতিবাচক কারণে ক্র্যাশ হওয়ার কোনও জাল নেই।


-3

এটা নির্ভর করে. যদি কোডের প্রয়োজনীয়তাগুলি স্পষ্টভাবে নথিভুক্ত থাকে তবে দৃ always়তা সর্বদা প্রয়োজনীয়তার সাথে মেলে। যে ক্ষেত্রে এটি একটি ভাল জিনিস। তবে, যদি কোনও প্রয়োজনীয়তা বা খারাপভাবে লিখিত প্রয়োজনীয়তা না থাকে, তবে নতুন প্রোগ্রামারদের জন্য প্রয়োজনীয় প্রতিটি প্রয়োজনীয়তাগুলি কী তা নির্ধারণের জন্য প্রতিবার ইউনিট পরীক্ষার উল্লেখ না করে কোড সম্পাদনা করা শক্ত হবে।


3
এই অফারটি কোন কিছুরই সৃষ্টি পয়েন্ট উপর সারগর্ভ বলে মনে হচ্ছে না এবং পূর্বে 8 উত্তর ব্যাখ্যা
মশা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.