এটি কি সত্য যে goto
ডেস্ট্রাক্টর এবং জিনিসগুলিকে কল না করে কোডের বিটগুলি জুড়ে যায়?
যেমন
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
x
ফাঁস হবে না ?
এটি কি সত্য যে goto
ডেস্ট্রাক্টর এবং জিনিসগুলিকে কল না করে কোডের বিটগুলি জুড়ে যায়?
যেমন
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
x
ফাঁস হবে না ?
"Won't x be leaked"
মানে? প্রকারটি x
একটি অন্তর্নির্মিত ডেটা টাইপ। কেন আপনি একটি ভাল উদাহরণ চয়ন করবেন না?
goto
, তারা মনে করে যে এমনকি স্বয়ংক্রিয় স্টোরেজ সময়কালের ভেরিয়েবলগুলি কোনওভাবে "ফাঁস" হয়। আপনি এবং আমি অন্যথায় জানি যে বিন্দু ছাড়াও সম্পূর্ণ।
int
ফুটো করতে পারে না, এটি ফাঁস হতে পারে । উদাহরণস্বরূপ: void f(void) { new int(5); }
ফাঁস an int
।
উত্তর:
সতর্কতা: এই উত্তরটি কেবলমাত্র সি ++ এর সাথে সম্পর্কিত ; নিয়মগুলি সিতে বেশ আলাদা are
x
ফাঁস হবে না ?
না, একেবারে না।
এটি একটি পৌরাণিক কাহিনী যা goto
কিছু নিম্ন-স্তরের নির্মাণ যা আপনাকে সি ++ এর অন্তর্নির্মিত স্কোপিং প্রক্রিয়াগুলিকে ওভাররাইড করতে দেয়। (যদি কিছু হয় তবে এটি longjmp
প্রবণ হতে পারে))
নিম্নলিখিত মেকানিকগুলি বিবেচনা করুন যা আপনাকে লেবেলগুলির সাথে "খারাপ জিনিস" করা থেকে বিরত রাখে (এতে case
লেবেল অন্তর্ভুক্ত রয়েছে )।
আপনি কার্যগুলি অতিক্রম করতে পারবেন না:
void f() {
int x = 0;
goto lol;
}
int main() {
f();
lol:
return 0;
}
// error: label 'lol' used but not defined
[n3290: 6.1/1]:
[..] একটি লেবেলের সুযোগ হ'ল ফাংশন যা এটি প্রদর্শিত হয়। [..]
আপনি অবজেক্টের সূচনাতে লাফিয়ে উঠতে পারবেন না:
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
কোনো সমস্যার জন্য, কিন্তু এটা না মানে এটি প্রায় সাধারণ শ্রুতি বিশালাকার মানুষ বিশ্বাস করতে হিসাবে "মন্দ" হিসাবে নয়।