গোটো ফুটো ভেরিয়েবলগুলি ব্যবহার করবে?


94

এটি কি সত্য যে gotoডেস্ট্রাক্টর এবং জিনিসগুলিকে কল না করে কোডের বিটগুলি জুড়ে যায়?

যেমন

void f() {
   int x = 0;
   goto lol;
}

int main() {
   f();
lol:
   return 0;
}

xফাঁস হবে না ?


সম্পর্কিত: স্ট্যাকওভারফ্লো / প্রশ্ন / 1258201/… (তবে আমি এটিকে স্ক্র্যাচ থেকে পরিষ্কার করেই করতে চেয়েছিলাম!)
অরবিটে লাইটনেস রেস

15
কী "Won't x be leaked"মানে? প্রকারটি xএকটি অন্তর্নির্মিত ডেটা টাইপ। কেন আপনি একটি ভাল উদাহরণ চয়ন করবেন না?
নওয়াজ

4
@ নাওয়াজ: উদাহরণটি এটির মতো নিখুঁত। প্রায় প্রতিবার আমি কারও সাথে কথা বলি goto, তারা মনে করে যে এমনকি স্বয়ংক্রিয় স্টোরেজ সময়কালের ভেরিয়েবলগুলি কোনওভাবে "ফাঁস" হয়। আপনি এবং আমি অন্যথায় জানি যে বিন্দু ছাড়াও সম্পূর্ণ।
অরবিটে লাইটনেস রেস

4
@ ডেভিড: আমি সম্মত হই যে যখন ভেরিয়েবলটির একটি তুচ্ছ ত্রুটিযুক্ত ডেস্ট্রাক্টর থাকে তখন আমি এই প্রশ্নটি আরও অনেক অর্থপূর্ণ করে তুলি ... এবং আমি তোমালকের উত্তরে সন্ধান করেছি এবং এরকম উদাহরণ পেয়েছি। তদ্ব্যতীত, একটি যখন intফুটো করতে পারে না, এটি ফাঁস হতে পারে । উদাহরণস্বরূপ: void f(void) { new int(5); }ফাঁস an int
বেন ভয়েগট

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

উত্তর:


210

সতর্কতা: এই উত্তরটি কেবলমাত্র সি ++ এর সাথে সম্পর্কিত ; নিয়মগুলি সিতে বেশ আলাদা are


xফাঁস হবে না ?

না, একেবারে না।

এটি একটি পৌরাণিক কাহিনী যা gotoকিছু নিম্ন-স্তরের নির্মাণ যা আপনাকে সি ++ এর অন্তর্নির্মিত স্কোপিং প্রক্রিয়াগুলিকে ওভাররাইড করতে দেয়। (যদি কিছু হয় তবে এটি longjmpপ্রবণ হতে পারে))

নিম্নলিখিত মেকানিকগুলি বিবেচনা করুন যা আপনাকে লেবেলগুলির সাথে "খারাপ জিনিস" করা থেকে বিরত রাখে (এতে caseলেবেল অন্তর্ভুক্ত রয়েছে )।


1. লেবেল সুযোগ

আপনি কার্যগুলি অতিক্রম করতে পারবেন না:

void f() {
   int x = 0;
   goto lol;
}

int main() {
   f();
lol:
   return 0;
}

// error: label 'lol' used but not defined

[n3290: 6.1/1]:[..] একটি লেবেলের সুযোগ হ'ল ফাংশন যা এটি প্রদর্শিত হয়। [..]


2. বিষয় সূচনা

আপনি অবজেক্টের সূচনাতে লাফিয়ে উঠতে পারবেন না:

int main() {
   goto lol;
   int x = 0;
lol:
   return 0;
}

// error: jump to label ‘lol’
// error:   from here
// error:   crosses initialization of ‘int x’

যদি আপনি অবজেক্টের সূচনাতে পিছনে ঝাঁপ দেন , তবে অবজেক্টটির পূর্ববর্তী "উদাহরণ" ধ্বংস হয়ে যাবে :

struct T {
   T() { cout << "*T"; }
  ~T() { cout << "~T"; }
};

int main() {
   int x = 0;

  lol:
   T t;
   if (x++ < 5)
     goto lol;
}

// Output: *T~T*T~T*T~T*T~T*T~T*T~T

[n3290: 6.6/2]:[..] একটি লুপের বাইরে, কোনও ব্লকের বাইরে স্থানান্তর, বা স্বয়ংক্রিয় স্টোরেজ সময়কাল সহ একটি প্রাথমিক ভেরিয়েবলের অতীত স্থানান্তরিত বিন্দুতে স্থানান্তরিত বিন্দুতে নয় তবে স্থানান্তরিত বিন্দুতে নয় এমন স্বয়ংক্রিয় স্টোরেজ সময়কাল সহ অবজেক্টগুলির ধ্বংসের সাথে জড়িত থাকে । [..]

আপনি কোনও সামগ্রীর স্কোপটিতে লাফিয়ে উঠতে পারবেন না, এমনকি এটি স্পষ্টভাবে সূচনা না করা থাকলেও:

int main() {
   goto lol;
   {
      std::string x;
lol:
      x = "";
   }
}

// error: jump to label ‘lol’
// error:   from here
// error:   crosses initialization of ‘std::string x’

... নির্দিষ্ট ধরণের অবজেক্ট ব্যতীত , ভাষা নির্বিশেষে ভাষা পরিচালনা করতে পারে কারণ তাদের "জটিল" নির্মাণের প্রয়োজন নেই:

int main() {
   goto lol;
   {
      int x;
lol:
      x = 0;
   }
}

// OK

[n3290: 6.7/3]:কোনও ব্লকে স্থানান্তর করা সম্ভব, তবে এমনভাবে নয় যে সূচনা দিয়ে ঘোষণাকে বাইপাস করে। যে প্রোগ্রামটি এমন একটি বিন্দু থেকে লাফ দেয় যেখানে স্বয়ংক্রিয় স্টোরেজ সময়কালের সাথে একটি ভেরিয়েবল এমন বিন্দুতে স্কোপ হয় না যেখানে এটি স্কোপতে থাকে তবে ভেরিয়েবলের স্কেলার টাইপ না হয়, তুচ্ছ ডিফল্ট কনস্ট্রাক্টর সহ ক্লাস টাইপ এবং ট্রিভিয়াল ডেস্ট্রাক্টর, একটি এই ধরণের একটির সিভি-কোয়ালিটিড সংস্করণ বা পূর্ববর্তী ধরণেরগুলির একটি অ্যারে এবং ইনিশিয়ালাইজার ছাড়াই ঘোষণা করা হয়। [..]


৩. জাম্পিং অন্যান্য অবজেক্টের স্কোপ দ্বারা মেনে চলে

অনুরূপভাবে, স্বয়ংক্রিয় স্টোরেজ সময়কাল সঙ্গে বস্তু হয় না "ফাঁস" আপনি যখন gotoতাদের সাধ্যের বাইরে :

struct T {
   T() { cout << "*T"; }
  ~T() { cout << "~T"; }
};

int main() {
   {
      T t;
      goto lol;
   }

lol:
   return 0;
}

// *T~T

[n3290: 6.6/2]:স্কোপ থেকে প্রস্থান করার সময় (তবে সম্পন্ন হয়েছে), স্বয়ংক্রিয় স্টোরেজ সময়কাল (৩. ).৩) এর সাথে যে স্কোপগুলি নির্মিত হয়েছে সেগুলি তাদের নির্মাণের বিপরীত ক্রমে নষ্ট হয়ে যায়। [..]


উপসংহার

উপরোক্ত প্রক্রিয়াগুলি এটি নিশ্চিত করে goto আপনাকে ভাষা ভাঙ্গতে দেয় না।

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


8
আপনি লক্ষ্য করতে পারেন যে সি এই সমস্ত বিপজ্জনক জিনিসগুলি ঘটতে বাধা দেয় না।
ড্যানিয়েল

13
@ ড্যানিয়েল: প্রশ্নোত্তরটি সি ++ সম্পর্কে সঠিকভাবে তবে সঠিক বিষয়। হতে পারে আমাদের কাছে আরও একটি FAQ থাকতে পারে যে পৌরাণিক কাহিনীটি বহন করে যা C এবং C ++ একই;)
অরবিটের লাইটনেস রেস

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

4
আপনি আরও যুক্ত করতে চাইবেন যে অন্তর্বর্তীকরণের জিনিসগুলির উপরে এই সমস্ত জাম্পিং কেস লেবেলের ক্ষেত্রে একই।
প্লাজমাএইচ

12
বাহ, আমি সবেমাত্র ধরে নিয়েছিলাম যে সি ++ এর শব্দার্থবিজ্ঞানগুলি গোটোয়ের জন্য ভেঙে গেছে, তবে তারা আশ্চর্যরকম বুদ্ধিমান! দুর্দান্ত উত্তর।
জোসেফ গারভিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.