কেন গোটো বিপজ্জনক?
goto
অস্থিরতা নিজেই সৃষ্টি করে না। প্রায় ১০,০০,০০০ goto
এর পরেও লিনাক্স কার্নেলটি স্থিরতার মডেল।
goto
নিজে থেকে সুরক্ষিত দুর্বলতা সৃষ্টি করা উচিত নয়। তবে কয়েকটি ভাষায়, এটি try
/ catch
ব্যতিক্রম পরিচালনা ব্লকগুলির সাথে মিশ্রণের ফলে এই সিইআরটি সুপারিশ অনুসারে বর্ণিত দুর্বলতাগুলি হতে পারে । মূলধারার সি ++ সংকলকগুলি এ জাতীয় ত্রুটিগুলি পতাকাঙ্কিত করে এবং প্রতিরোধ করে, তবে দুর্ভাগ্যক্রমে, পুরানো বা আরও বহিরাগত সংকলকগুলি এটি করে না।
goto
অপঠনযোগ্য এবং অনিবার্য কোডের কারণ। এটিকে স্প্যাগেটি কোডও বলা হয় , কারণ স্প্যাগেটি প্লেটের মতো, যখন অনেকগুলি গোটো থাকে তখন নিয়ন্ত্রণের প্রবাহকে অনুসরণ করা খুব কঠিন।
এমনকি যদি আপনি স্প্যাগেটি কোড এড়াতে পরিচালনা করেন এবং আপনি যদি কয়েকটি গোটো ব্যবহার করেন তবে সেগুলি তবুও বাগের মতো এবং রিসোর্স ফাঁসকে সহজতর করে:
- স্পষ্ট নেস্টেড ব্লক এবং লুপ বা সুইচ সহ স্ট্রাকচার প্রোগ্রামিং ব্যবহার করে কোড অনুসরণ করা সহজ; এর নিয়ন্ত্রণের প্রবাহটি খুব অনুমানযোগ্য। অতএব আক্রমণকারীরা শ্রদ্ধা হয় তা নিশ্চিত করা আরও সহজ।
- একটি
goto
বিবৃতি দিয়ে, আপনি সেই সোজা প্রবাহটি ভঙ্গ করেন এবং প্রত্যাশাগুলি ভঙ্গ করেন। উদাহরণস্বরূপ, আপনি খেয়াল করতে পারেন না যে আপনার এখনও নিখরচায় সংস্থান আছে।
goto
বিভিন্ন জায়গায় অনেকগুলি আপনাকে একক গোটো টার্গেটে পাঠাতে পারে। সুতরাং এই জায়গায় পৌঁছানোর সময় আপনি যে রাজ্যে রয়েছেন তা নিশ্চিতভাবে জানা জেনে রাখা স্পষ্ট নয়। ভুল / ভিত্তিহীন অনুমান করার ঝুঁকি তাই বেশ বড়।
অতিরিক্ত তথ্য এবং উদ্ধৃতি:
সি goto
শাখায় অসীম-আপত্তিজনক বিবৃতি এবং লেবেল সরবরাহ করে। সাধারণত goto
এটি কখনই প্রয়োজন হয় না এবং অনুশীলনে এটি ছাড়া কোড লেখা প্রায় সবসময়ই সহজ। (...)
তবুও আমরা কয়েকটি পরিস্থিতি প্রস্তাব করব যেখানে সেখানে কোনও জায়গা খুঁজে পেতে পারে। সর্বাধিক সাধারণ ব্যবহার হ'ল কিছু গভীর নেস্টেড স্ট্রাকচারগুলিতে প্রক্রিয়াজাতকরণ ত্যাগ করা, যেমন একবারে দুটি লুপ ভাঙা। (...)
যদিও আমরা বিষয়টি সম্পর্কে মতামতী নই, তবে মনে হয় গোটো বিবৃতি কিছুটা হলেও অল্প ব্যবহার করা উচিত ।
কখন ব্যবহার করা যাবে?
কে অ্যান্ড আর এর মতো আমি গোটোস সম্পর্কে গোপনীয় নই। আমি স্বীকার করি যে এমন কিছু পরিস্থিতি রয়েছে যেখানে গেটো কারও জীবনকে সহজ করা যায়।
সাধারণত সি তে, গেটো মাল্টিলেভাল লুপ থেকে বেরিয়ে যাওয়ার অনুমতি দেয় বা ত্রুটি পরিচালনার জন্য প্রয়োজনীয় প্রস্থান বিন্দুতে পৌঁছতে প্রয়োজনীয় যেগুলি এতক্ষণে বরাদ্দকৃত সমস্ত সংস্থানকে মুক্ত / আনলক করে (যেমন ক্রম অনুসারে একাধিক বরাদ্দ একাধিক লেবেল)। এই নিবন্ধটি লিনাক্স কার্নেলের গোটোর বিভিন্ন ব্যবহারের পরিমাণ নির্ধারণ করেছে।
ব্যক্তিগতভাবে আমি এড়াতে পছন্দ করি এবং 10 বছরের সিতে, আমি সর্বোচ্চ 10 গোটো ব্যবহার করি। আমি নেস্টেড if
এস ব্যবহার করতে পছন্দ করি, যা আমার মনে হয় আরও বেশি পঠনযোগ্য। এটি যখন খুব গভীর বাসা বাঁধে তখন আমি আমার ফাংশনটি ছোট ছোট অংশে পচে যাওয়া বা ক্যাসকেডে বুলিয়ান সূচক ব্যবহার করতে পছন্দ করতাম। আজকের অনুকূলকরণ সংকলকগুলি একই কোড সহ প্রায় একই কোড উত্পন্ন করতে যথেষ্ট চৌকস goto
।
গোটোর ব্যবহার ভাষার উপর নির্ভর করে:
সি ++ এ, আরআইআই এর যথাযথ ব্যবহারের ফলে সংকলকটি সুযোগের বাইরে চলে যাওয়া সামগ্রীগুলি স্বয়ংক্রিয়ভাবে ধ্বংস করে দেয়, যাতে সংস্থানগুলি / লকটি যে কোনও উপায়ে পরিষ্কার করা যায়, এবং আর কিছুই করার দরকার নেই।
জাভা (উপরে জাভার লেখক উদ্ধৃতি এবং এই দেখতে এতে যান জন্য কোন প্রয়োজন আছে চমৎকার স্ট্যাক ওভারফ্লো উত্তর ): আবর্জনা সংগ্রাহক সাফ করে যে জগাখিচুড়ি, break
, continue
, এবং try
/ catch
ব্যতিক্রম হ্যান্ডলিং সব ক্ষেত্রে যেখানে আবরণ goto
সহায়ক হতে পারে, কিন্তু একটি নিরাপদ এবং ভাল বইতে দেবেন। জাভার জনপ্রিয়তা প্রমাণ করে যে আধুনিক ভাষায় গোটো স্টেটমেন্ট এড়ানো যায়।
বিখ্যাত এসএসএল জুমটি দুর্বলতায় ব্যর্থ হয়েছে
গুরুত্বপূর্ণ অস্বীকৃতি: মন্তব্যে উগ্র আলোচনার প্রেক্ষিতে আমি স্পষ্ট করে বলতে চাই যে আমি যে ভঙ্গী বিবৃতি এই বাগের একমাত্র কারণ, তা ভেবে দেখছি না। আমি ভান করি না যে গোটো ছাড়া কোনও বাগ থাকবে না। আমি কেবল দেখাতে চাই যে একটি গোটো একটি গুরুতর বাগে জড়িত হতে পারে।
goto
প্রোগ্রামিংয়ের ইতিহাসে কতগুলি গুরুতর বাগ সম্পর্কিত তা আমি জানি না : বিবরণটি প্রায়শই জানানো হয় না। তবে একটি বিখ্যাত অ্যাপল এসএসএল বাগ ছিল যা আইওএসের সুরক্ষা দুর্বল করেছিল। যে বিবৃতিটি এই বাগের দিকে নিয়েছিল তা একটি ভুল goto
বক্তব্য ছিল।
কিছু যুক্তি দেয় যে বাগের মূল কারণটি নিজের মধ্যে গোটো স্টেটমেন্ট ছিল না, তবে একটি ভুল অনুলিপি / পেস্ট, একটি বিভ্রান্তিকর ইন্ডেন্টেশন, শর্তাধীন ব্লকের চারপাশে কোঁকড়ানো ধনুর্বন্ধনী অনুপস্থিত বা সম্ভবত বিকাশকারীর কাজের অভ্যাস ছিল। আমি সেগুলির কোনওটিই নিশ্চিত করতে পারি না: এই সমস্ত যুক্তিই সম্ভাব্য অনুমান এবং ব্যাখ্যা। আসলেই কেউ জানে না। ( ইতিমধ্যে, মন্তব্যে কেউ পরামর্শ দেওয়ার সাথে সাথে একীকরণের অনুমানটি ভুল হয়ে গেছে যা একই ফাংশনে কিছু অন্যান্য ইনডেন্টেশন অসঙ্গতি বিবেচনা করে খুব ভাল প্রার্থী বলে মনে হয় )।
একমাত্র উদ্দেশ্যগত সত্যটি হ'ল একটি অনুলিপি goto
নেতৃত্বাধীন অকাল থেকেই কার্য থেকে বেরিয়ে আসে। কোডটি দেখলে, কেবলমাত্র একক বিবৃতি যা একই প্রভাবের কারণ হতে পারে তা ফিরে আসতে পারত।
ত্রুটি ফাংশন রয়েছে SSLEncodeSignedServerKeyExchange()
মধ্যে এই ফাইলটি :
if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
goto fail;
if ((err =...) !=0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail; // <====OUCH: INDENTATION MISLEADS: THIS IS UNCONDITIONDAL!!
if (...)
goto fail;
... // Do some cryptographic operations here
fail:
... // Free resources to process error
কন্ডিশনাল ব্লকের চারপাশে কোঁকড়ানো ধনুর্বন্ধনীগুলি বাগটি আটকাতে পারত:
এটি সংকলনের সময় সিনট্যাক্স ত্রুটির কারণ হয়ে উঠত (এবং তাই একটি সংশোধন) অথবা একটি নিরর্থক ক্ষতিহীন গোটোতে পরিণত হত। যাইহোক, জিসিসি 6 অসঙ্গতিযুক্ত ইনডেন্টেশন সনাক্ত করতে এর alচ্ছিক সতর্কতার জন্য ধন্যবাদ এই ত্রুটিগুলি চিহ্নিত করতে সক্ষম করবে।
তবে প্রথমত, আরও কাঠামোগত কোডের সাহায্যে এই সমস্ত গোটগুলি এড়ানো যেত। সুতরাং গোটো অন্তত পরোক্ষভাবে এই বাগের কারণ। কমপক্ষে দুটি ভিন্ন উপায় রয়েছে যা এড়াতে পারত:
পদ্ধতির 1: যদি ক্লজ বা নেস্টেড if
এস
ক্রমানুসারে ত্রুটির জন্য প্রচুর শর্ত পরীক্ষা করার পরিবর্তে, এবং fail
সমস্যাগুলির ক্ষেত্রে প্রতিবার কোনও লেবেলে প্রেরণ করার পরিবর্তে, if
কোনও ব্যক্তি পূর্ব-শর্তে ক্রিপ্টোগ্রাফিক ক্রিয়াকলাপগুলি সম্পাদন করার পক্ষে বেছে নিতে পারেন যা কোনও ভুল প্রাক-শর্ত না থাকলেই এটি করতে পারে:
if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) == 0 &&
(err = ...) == 0 ) &&
(err = ReadyHash(&SSLHashSHA1, &hashCtx)) == 0) &&
...
(err = ...) == 0 ) )
{
... // Do some cryptographic operations here
}
... // Free resources
পদ্ধতির 2: একটি ত্রুটি সংযোজক ব্যবহার করুন
এই পদ্ধতির উপর ভিত্তি করে যে এখানে প্রায় সমস্ত বিবৃতি err
ত্রুটি কোড সেট করতে কিছু ফাংশন কল করে এবং বাকী কোডটি কেবল err
0 হলে (যেমন ত্রুটি ছাড়াই কার্যকর করা ফাংশন) কল করে। একটি দুর্দান্ত নিরাপদ এবং পঠনযোগ্য বিকল্প হ'ল:
bool ok = true;
ok = ok && (err = ReadyHash(&SSLHashSHA1, &hashCtx))) == 0;
ok = ok && (err = NextFunction(...)) == 0;
...
ok = ok && (err = ...) == 0;
... // Free resources
এখানে, একটিও গোটো নেই: ব্যর্থতার প্রস্থান পয়েন্টে দ্রুত ঝাঁপিয়ে পড়ার ঝুঁকি নেই। এবং দৃশ্যত এটি একটি ভুল বিভক্ত রেখা বা একটি ভুলে যাওয়া চিহ্নিত করা সহজ হবে ok &&
।
এই কনস্ট্রাক্টটি আরও কমপ্যাক্ট। এটি সি এর ভিত্তিতে একটি যৌক্তিক এবং ( &&
) এর দ্বিতীয় অংশটি প্রথম অংশটি সত্য হলেই মূল্যায়ন করা হয় on প্রকৃতপক্ষে, একটি অপ্টিমাইজ করা সংকলক দ্বারা উত্পন্ন এসেমব্লারটি গোটোসের সাথে মূল কোডের প্রায় সমান: অপটিমাইজারটি শর্তগুলির শৃঙ্খলাটি খুব ভালভাবে আবিষ্কার করে এবং কোড উত্পন্ন করে, যা প্রথম নাল রিটার্ন মানটি শেষের দিকে যায় ( অনলাইন প্রমাণ )।
এমনকি আপনি ফাংশনের শেষে একটি ধারাবাহিকতা পরীক্ষা করতে পারেন যা পরীক্ষার পর্যায়ে ঠিক পতাকা এবং ত্রুটির কোডের মধ্যে মিল খুঁজে পাওয়া যায় না।
assert( (ok==false && err!=0) || (ok==true && err==0) );
যেমন একটি ভুল ==0
একটি সঙ্গে অনবধানতাবশত প্রতিস্থাপিত !=0
বা যৌক্তিক সংযোজক ত্রুটি সহজে ডিবাগিং সময়ে বিক্ষোভ করা হবে।
যেমনটি বলেছেন: আমি ভান করি না যে বিকল্প নির্মাণগুলি কোনও ত্রুটি এড়াতে পারত। আমি কেবল এটিই বলতে চাই যে তারা ত্রুটিটি ঘটানো আরও জটিল করে তুলতে পারে।