সি তে, আপনি যদি স্পষ্টত ত্রুটি পরিচালনার জন্য + গেটো এর ম্যানুয়াল ব্যবহারের মাধ্যমে স্বয়ংক্রিয় "অবজেক্ট পুনঃনির্মাণ" ব্যতিক্রমগুলি "সিমুলেট" করতে পারেন।
আমি প্রায়শই নীচের মতো সি কোডটি লিখি (ত্রুটি পরিচালনার হাইলাইট করতে সিদ্ধ হয়ে):
#include <assert.h>
typedef int errcode;
errcode init_or_fail( foo *f, goo *g, poo *p, loo *l )
{
errcode ret = 0;
if ( ( ret = foo_init( f ) ) )
goto FAIL;
if ( ( ret = goo_init( g ) ) )
goto FAIL_F;
if ( ( ret = poo_init( p ) ) )
goto FAIL_G;
if ( ( ret = loo_init( l ) ) )
goto FAIL_P;
assert( 0 == ret );
goto END;
/* error handling and return */
/* Note that we finalize in opposite order of initialization because we are unwinding a *STACK* of initialized objects */
FAIL_P:
poo_fini( p );
FAIL_G:
goo_fini( g );
FAIL_F:
foo_fini( f );
FAIL:
assert( 0 != ret );
END:
return ret;
}
এটি সম্পূর্ণ স্ট্যান্ডার্ড এএনএসআই সি, আপনার মূললাইন কোড থেকে দূরে পরিচালিত ত্রুটি পৃথক করে, সি ++ এর মতো আরম্ভকৃত বস্তুগুলির (ম্যানুয়াল) স্ট্যাক আনওয়ানডিংয়ের অনুমতি দেয় এবং এখানে কী ঘটছে তা সম্পূর্ণ স্পষ্ট obvious যেহেতু আপনি স্পষ্টভাবে প্রতিটি পয়েন্টে ব্যর্থতার জন্য পরীক্ষা করছেন এটি নির্দিষ্ট লগিং orোকানো বা প্রতিটি জায়গায় ত্রুটি হ্যান্ডলিংয়ে ত্রুটি দেখা দিতে পারে সহজ করে তোলে।
যদি আপনি সামান্য ম্যাক্রো যাদু মনে করেন না, তবে স্ট্যাক ট্রেস সহ লগিং ত্রুটির মতো অন্যান্য জিনিসগুলি করার সময় আপনি এটিকে আরও সংক্ষিপ্ত করে তুলতে পারেন। উদাহরণ স্বরূপ:
#include <assert.h>
#include <stdio.h>
#include <string.h>
#define TRY( X, LABEL ) do { if ( ( X ) ) { fprintf( stderr, "%s:%d: Statement '" #X "' failed! %d, %s\n", __FILE__, __LINE__, ret, strerror( ret ) ); goto LABEL; } while ( 0 )
typedef int errcode;
errcode init_or_fail( foo *f, goo *g, poo *p, loo *l )
{
errcode ret = 0;
TRY( ret = foo_init( f ), FAIL );
TRY( ret = goo_init( g ), FAIL_F );
TRY( ret = poo_init( p ), FAIL_G );
TRY( ret = loo_init( l ), FAIL_P );
assert( 0 == ret );
goto END;
/* error handling and return */
FAIL_P:
poo_fini( p );
FAIL_G:
goo_fini( g );
FAIL_F:
foo_fini( f );
FAIL:
assert( 0 != ret );
END:
return ret;
}
অবশ্যই এটি সি ++ ব্যতিক্রম + ধ্বংসকারীদের মতো মার্জিত নয়। উদাহরণস্বরূপ, এইভাবে একটি ফাংশনের মধ্যে একাধিক ত্রুটি হ্যান্ডলিং স্ট্যাকগুলি বাসা বাঁধা খুব পরিষ্কার নয়। পরিবর্তে, আপনি সম্ভবত সেগুলি নিজের মধ্যে থাকা সাব ফাংশনগুলিতে বিভক্ত করতে চান যা একইভাবে ত্রুটিগুলি পরিচালনা করে, প্রারম্ভিক করে + এভাবে পরিষ্কারভাবে চূড়ান্ত করে।
এটি কেবলমাত্র একটি একক ক্রিয়াকলাপের মধ্যেও কাজ করে এবং উচ্চ স্তরের কলাররা একই রকম স্পষ্ট ত্রুটি পরিচালনার যুক্তিকে বাস্তবায়ন না করা পর্যন্ত স্ট্যাকটি লাফিয়ে রাখবে না, যদিও একটি সি ++ ব্যতিক্রম উপযুক্ত হ্যান্ডলার খুঁজে না পাওয়া পর্যন্ত কেবল স্ট্যাকটি লাফিয়ে উঠতে থাকবে। বা এটি আপনাকে একটি স্বেচ্ছাসেবী টাইপ নিক্ষেপ করার অনুমতি দেয় না, পরিবর্তে কেবল একটি ত্রুটি কোড।
পদ্ধতিগতভাবে এইভাবে কোডিং (যেমন - একক এন্ট্রি এবং একক প্রস্থান পয়েন্ট সহ) প্রাক এবং পোস্ট ("শেষ অবধি") যুক্তি সন্নিবেশ করা খুব সহজ করে তোলে যা নির্বিশেষে যাই হোক না কেন। আপনি মাত্র "লেবেলটি" শেষের লেবেলের পরে রেখেছেন put