volatile
সি তে কেন দরকার? এটা কি কাজে লাগে? এটা কি করবে?
volatile
সি তে কেন দরকার? এটা কি কাজে লাগে? এটা কি করবে?
উত্তর:
উদ্বোধকটি কম্পাইলারকে বলে যে কোনও কিছুকেই উদ্বায়ী ভেরিয়েবলের সাথে অনুকূল করতে হবে না।
এটি ব্যবহার করার জন্য কমপক্ষে তিনটি সাধারণ কারণ রয়েছে, সমস্তগুলি এমন পরিস্থিতিতে জড়িত যেখানে ভেরিয়েবলের মান দৃশ্যমান কোড থেকে ব্যবস্থা না নিয়ে পরিবর্তন করতে পারে: আপনি যখন হার্ডওয়্যারটির সাথে ইন্টারফেস করেন যা মানটি নিজেই পরিবর্তন করে; যখন অন্য থ্রেড চলমান থাকে যা চলকটিও ব্যবহার করে; বা যখন এমন সিগন্যাল হ্যান্ডলার থাকে যা ভেরিয়েবলের মান পরিবর্তন করতে পারে।
ধরা যাক আপনার কাছে একটি সামান্য টুকরো হার্ডওয়্যার রয়েছে যা কোথাও র্যামে ম্যাপ করা হয়েছে এবং এর দুটি ঠিকানা রয়েছে: একটি কমান্ড পোর্ট এবং একটি ডেটা পোর্ট:
typedef struct
{
int command;
int data;
int isbusy;
} MyHardwareGadget;
এখন আপনি কিছু আদেশ পাঠাতে চান:
void SendCommand (MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isbusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}
দেখতে সহজ মনে হচ্ছে, তবে এটি ব্যর্থ হতে পারে কারণ সংকলকটি যাতে আদেশ এবং ডেটা কমান্ড লিখিত থাকে সেটিকে পরিবর্তন করতে মুক্ত। এটি আমাদের ছোট গ্যাজেটটি পূর্ববর্তী ডেটা-মান সহ কমান্ড জারি করতে পারে। ব্যস্ত লুপের সময় অপেক্ষাটিও একবার দেখুন। এটি একটি অপ্টিমাইজড হবে। সংকলকটি চালাক হওয়ার চেষ্টা করবে, ইসবসির মানটি একবার পড়বে এবং তারপরে অসীম লুপে যাবে। আপনি যা চান তা তা নয়।
এটির কাছে যাওয়ার উপায় হ'ল পয়েন্টার গ্যাজেটটিকে অস্থির হিসাবে ঘোষণা করা। এইভাবে সংকলক আপনি যা লিখেছেন তা করতে বাধ্য হয়। এটি মেমরির কার্যভারগুলি সরিয়ে ফেলতে পারে না, এটি রেজিস্টারে ভেরিয়েবলগুলি ক্যাশে করতে পারে না এবং এটি অ্যাসাইনমেন্টের ক্রমও পরিবর্তন করতে পারে না:
এটি সঠিক সংস্করণ:
void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isbusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}
volatile
সিতে আসলে ভেরিয়েবলের মানগুলি স্বয়ংক্রিয়ভাবে ক্যাশে না করার উদ্দেশ্যে অস্তিত্বের মধ্যে আসে। এটি কম্পাইলারকে এই ভেরিয়েবলের মান ক্যাশে না করতে বলবে। সুতরাং এটি volatile
প্রতিটি বারের মুখোমুখি হওয়ার সাথে সাথে মূল স্মৃতি থেকে প্রদত্ত ভেরিয়েবলের মান নিতে কোড উত্পন্ন করবে। এই মেকানিজমটি ব্যবহার করা হয় কারণ যে কোনও সময়ে ওএস দ্বারা মান পরিবর্তন করা যেতে পারে বা কোনও বিঘ্নিত হতে পারে। সুতরাং volatile
ব্যবহারটি আমাদের প্রতিবার নতুনভাবে অ্যাক্সেস করতে সহায়তা করবে।
volatile
ছিল কম্পাইলারদের কোড অপ্টিমাইজ করা সম্ভব করা যখন এখনও প্রোগ্রামাররা এই শব্দার্থক শব্দগুলি অর্জন করতে পারে যা এই ধরনের অপ্টিমাইজেশন ছাড়াই অর্জন করতে পারে। স্ট্যান্ডার্ডের লেখকরা প্রত্যাশা করেছিলেন যে লক্ষ্য প্রয়োগকারীরা তাদের লক্ষ্য প্ল্যাটফর্ম এবং অ্যাপ্লিকেশন ক্ষেত্রগুলি বিবেচনা করে যা কিছু শব্দার্থক কাজে লাগবে তা সমর্থন করবে এবং আশা করেনি যে সংকলক লেখকরা সর্বনিম্ন মানের শব্দার্থকগুলি প্রস্তাব করবে যা স্ট্যান্ডার্ডের সাথে সঙ্গতিপূর্ণ এবং 100% নয় বোকা (নোট করুন যে স্ট্যান্ডার্ডের লেখকরা স্পষ্টভাবে
এর জন্য আরেকটি ব্যবহার volatile
হ'ল সিগন্যাল হ্যান্ডলার। আপনার যদি এই জাতীয় কোড থাকে:
int quit = 0;
while (!quit)
{
/* very small loop which is completely visible to the compiler */
}
সংকলকটি লুপের বডিটি quit
ভেরিয়েবলটিকে স্পর্শ করে না এবং লুপটিকে একটি while (true)
লুপে রূপান্তর করতে পারে তা লক্ষ্য করার অনুমতি দেওয়া হয় । এমনকি যদি quit
ভেরিয়েবলটি সিগন্যাল হ্যান্ডলারের জন্য SIGINT
এবং এর জন্য সেট করা থাকে SIGTERM
; সংকলকটি এটি জানার কোনও উপায় নেই।
যাইহোক, যদি quit
ভেরিয়েবলটি ঘোষণা করা হয় volatile
তবে কম্পাইলারটি প্রতিবার এটি লোড করতে বাধ্য হয়, কারণ এটি অন্য কোথাও সংশোধন করা যেতে পারে। আপনি এই পরিস্থিতিতে ঠিক এটি চান।
quit
এটি একটি ধ্রুবক লুপে অনুকূলিত করতে পারে quit
পুনরাবৃত্তির মধ্যে পরিবর্তন করার কোনও উপায় নেই । এনবি: প্রকৃত থ্রেডস্যাফ প্রোগ্রামিংয়ের জন্য এটি অবশ্যই ভাল বিকল্প নয়।
volatile
বা অন্যান্য চিহ্নিতকারীদের অনুপস্থিতিতে , এটি ধরে নেওয়া হবে যে লুপের বাইরে কোনও কিছুই সেই পরিবর্তনশীলটিকে পরিবর্তন করে না যখন একবার লুপটিতে প্রবেশ করে, এমনকি এটি বৈশ্বিক পরিবর্তনশীল।
extern int global; void fn(void) { while (global != 0) { } }
সঙ্গে gcc -O3 -S
এবং তার ফলে সমাবেশ ফাইল তাকান, আমার মেশিনে এটা আছে movl global(%rip), %eax
; testl %eax, %eax
; je .L1
; .L4: jmp .L4
, অর্থাৎ, বিশ্বব্যাপী শূন্য না হলে একটি অসীম লুপ। তারপরে যুক্ত করার চেষ্টা করুন volatile
এবং পার্থক্যটি দেখুন।
volatile
সংকলকটিকে বলে যে আপনার কোডটি অ্যাক্সেস করছে এমন কোডের চেয়ে অন্য উপায় দ্বারা পরিবর্তিত হতে পারে। উদাহরণস্বরূপ, এটি আই / ও-ম্যাপযুক্ত মেমরির অবস্থান হতে পারে। যদি এই ক্ষেত্রে এটি নির্দিষ্ট না করা হয় তবে কিছু পরিবর্তনশীল অ্যাক্সেস অনুকূলিত করা যায়, উদাহরণস্বরূপ, এটির বিষয়বস্তু একটি রেজিস্টারে রাখা যেতে পারে এবং মেমরির অবস্থানটি আবার পড়তে পারে না।
আন্দ্রেই আলেকজান্দ্রেস্কুর এই নিবন্ধটি দেখুন, " অস্থির - মাল্টিথ্রেডেড প্রোগ্রামার সেরা বন্ধু "
উদ্বায়ী শব্দ কম্পাইলার অপ্টিমাইজেশন যে কোড নির্দিষ্ট অ্যাসিঙ্ক্রোনাস ঘটনা উপস্থিতিতে ভুল রেন্ডার পারে প্রতিরোধ চিন্তিত ছিল। উদাহরণস্বরূপ, আপনি যদি কোনও আদিম পরিবর্তনশীলটিকে অস্থির হিসাবে ঘোষণা করেন তবে সংকলকটিকে এটি একটি রেজিস্টারে ক্যাশে রাখার অনুমতি নেই - একটি সাধারণ অপ্টিমাইজেশন যা ভেরিয়েবলটি একাধিক থ্রেডের মধ্যে ভাগ করা গেলে বিপর্যয়কর হবে। সুতরাং সাধারণ নিয়মটি হল, আপনার যদি আদিম ধরণের ভেরিয়েবলগুলি থাকে যা অবশ্যই একাধিক থ্রেডের মধ্যে ভাগ করা উচিত, সেই পরিবর্তনগুলি অস্থির হিসাবে ঘোষণা করুন। তবে আপনি এই কীওয়ার্ডটি দিয়ে আসলে আরও অনেক কিছু করতে পারেন: আপনি থ্রেডটি নিরাপদ নয় এমন কোডটি ধরতে এটি ব্যবহার করতে পারেন এবং সংকলনের সময় আপনি এটি করতে পারেন। এই নিবন্ধটি দেখায় যে এটি কীভাবে করা হয়; সমাধানটিতে একটি সাধারণ স্মার্ট পয়েন্টার জড়িত যা কোডের জটিল বিভাগগুলিকে সিরিয়ালাইজ করা সহজ করে তোলে।
নিবন্ধটি উভয় ক্ষেত্রে প্রযোজ্য C
এবং C++
।
স্কট মায়ারস এবং আন্দ্রে আলেকজান্দ্রেস্কুর " সি ++ এবং ডাবল-চেকড লকিংয়ের বিপদগুলি " নিবন্ধটি দেখুন :
তাই কিছু মেমোরি অবস্থানের সাথে কাজ করার সময় (যেমন মেমরি ম্যাপযুক্ত পোর্ট বা আইএসআর দ্বারা ব্যবহৃত মেমরি [[বিঘ্নিত পরিষেবার রুটিন]]) কিছু অপ্টিমাইজেশন স্থগিত করতে হবে। এই জায়গাগুলির জন্য বিশেষ চিকিত্সা নির্দিষ্ট করার জন্য অস্থির উপস্থিতি রয়েছে, বিশেষত: (1) একটি উদ্বায়ী ভেরিয়েবলের বিষয়বস্তু "অস্থির" (সংকলকের অজানা মাধ্যমে পরিবর্তিত হতে পারে), (২) অস্থির ডেটাগুলিতে সমস্ত লিখেছে "পর্যবেক্ষণযোগ্য" তাই তারা অবশ্যই ধর্মীয়ভাবে মৃত্যুদন্ড কার্যকর করা উচিত এবং (3) অস্থির ডেটাতে সমস্ত ক্রিয়াকলাপ ক্রম অনুসারে কার্যকর করা হয় যেখানে তারা উত্স কোডে প্রদর্শিত হয়। প্রথম দুটি নিয়ম যথাযথ পড়া এবং লেখা নিশ্চিত করে। সর্বশেষ একটি ইনপুট এবং আউটপুটকে মেশানো I / O প্রোটোকলগুলির প্রয়োগের অনুমতি দেয়। এটি অনানুষ্ঠানিকভাবে সি এবং সি ++ এর অস্থির গ্যারান্টিযুক্ত।
volatile
পারমাণবিকতা গ্যারান্টি দেয় না।
আমার সহজ ব্যাখ্যাটি হ'ল:
কিছু দৃশ্যে, যুক্তি বা কোডের উপর ভিত্তি করে, সংকলক পরিবর্তনশীলগুলির অপ্টিমাইজেশন করবে যা মনে করে যে এটি পরিবর্তন হয় না। volatile
শব্দ প্রতিরোধ একটি পরিবর্তনশীল অপ্টিমাইজ করা হচ্ছে।
উদাহরণ স্বরূপ:
bool usb_interface_flag = 0;
while(usb_interface_flag == 0)
{
// execute logic for the scenario where the USB isn't connected
}
উপরের কোড থেকে, সংকলকটি usb_interface_flag
0 হিসাবে সংজ্ঞায়িত হিসাবে মনে হতে পারে , এবং সেই সময় লুপটি চিরতরে শূন্য হবে। অপ্টিমাইজেশনের পরে, সংকলকটি এটি while(true)
সর্বকালের হিসাবে বিবেচনা করবে , যার ফলে অসীম লুপ হবে।
এই ধরণের পরিস্থিতি এড়াতে, আমরা পতাকাটিকে অস্থির হিসাবে ঘোষণা করি, আমরা সংকলককে বলছি যে এই মানটি কোনও বাহ্যিক ইন্টারফেস বা প্রোগ্রামের অন্য মডিউল দ্বারা পরিবর্তিত হতে পারে, দয়া করে এটি অপ্টিমাইজ করবেন না। এটি অস্থির জন্য ব্যবহারের কেস।
অস্থির জন্য একটি প্রান্তিক ব্যবহার নিম্নলিখিত। বলুন আপনি কোনও ফাংশনের সংখ্যাগত ডেরিভেটিভ গণনা করতে চান f
:
double der_f(double x)
{
static const double h = 1e-3;
return (f(x + h) - f(x)) / h;
}
সমস্যাটি হ'ল রাউন্ডঅফ ত্রুটির কারণে x+h-x
সাধারণত সমান হয় না h
। এটি সম্পর্কে চিন্তা করুন: আপনি যখন খুব কাছের সংখ্যার বিয়োগ করেন, আপনি প্রচুর উল্লেখযোগ্য সংখ্যা হারাবেন যা ডেরাইভেটিভের গণনাকে নষ্ট করতে পারে (চিন্তা করুন 1.00001 - 1)। একটি সম্ভাব্য কাজ হতে পারে
double der_f2(double x)
{
static const double h = 1e-3;
double hh = x + h - x;
return (f(x + hh) - f(x)) / hh;
}
তবে আপনার প্ল্যাটফর্ম এবং সংকলক সুইচগুলির উপর নির্ভর করে আক্রমণাত্মকভাবে অনুকূলিতকরণ সংকলক দ্বারা সেই ফাংশনের দ্বিতীয় লাইনটি মুছে ফেলা হতে পারে। সুতরাং আপনি পরিবর্তে লিখুন
volatile double hh = x + h;
hh -= x;
একটি সংক্ষিপ্ত অপ্টিমাইজেশান সুযোগকে হারাতে, এইচএইচ থাকা মেমরির অবস্থানটি পড়তে সংকলককে বাধ্য করতে।
h
বা hh
ডেরিভেটিভ সূত্র মধ্যে পার্থক্য কি ? কখন hh
গণনা করা হয় শেষ সূত্রটি এটিকে প্রথমটির মতো ব্যবহার করে, কোনও পার্থক্য ছাড়াই। এটা হতে হবে (f(x+h) - f(x))/hh
?
h
এবং hh
যে hh
অপারেশন দুটি কিছু নেতিবাচক ক্ষমতায় ছেঁটে ফেলা হয়েছে x + h - x
। এই ক্ষেত্রে, x + hh
এবং x
ঠিক দ্বারা পৃথক hh
। আপনি আপনার সূত্রটিও নিতে পারেন, এটি একই ফলাফল দেবে, যেহেতু x + h
এবং x + hh
সমান (এটি হ'ল যা এখানে গুরুত্বপূর্ণ।
x1=x+h; d = (f(x1)-f(x))/(x1-x)
? অস্থির ব্যবহার না করে।
-ffast-math
বা সমতুল্যভাবে স্পষ্টভাবে যদি বলা হয় তবে এটি অপ্টিমাইজ করার অনুমতি রয়েছে ।
দুটি ব্যবহার আছে। এম্বেডড ডেভলপমেন্টে এগুলি বিশেষত বেশি ব্যবহৃত হয়।
সংকলকটি অস্থায়ী কীওয়ার্ডের সাথে সংজ্ঞায়িত ভেরিয়েবলগুলি ব্যবহার করে এমন ফাংশনগুলি অনুকূল করবে না
অস্থিরতা র্যাম, রম ইত্যাদিতে সঠিক মেমোরি অবস্থানগুলিতে অ্যাক্সেস করতে ব্যবহৃত হয় ... মেমরি-ম্যাপযুক্ত ডিভাইসগুলি নিয়ন্ত্রণ করতে, সিপিইউ রেজিস্টারগুলিতে অ্যাক্সেস করতে এবং নির্দিষ্ট মেমরির অবস্থানগুলি সনাক্ত করতে এটি প্রায়শই ব্যবহৃত হয়।
সমাবেশ তালিকা সহ উদাহরণগুলি দেখুন। পুনরায়: এম্বেডড ডেভলপমেন্টে সি "অস্থির" কীওয়ার্ডের ব্যবহার
অস্থিরতাও দরকারী, যখন আপনি কম্পাইলারকে একটি নির্দিষ্ট কোড সিকোয়েন্সটি অনুকূলকরণ করতে বাধ্য করবেন না (যেমন মাইক্রো-বেঞ্চমার্ক লেখার জন্য)।
আমি অন্য একটি দৃশ্যের উল্লেখ করব যেখানে অস্থিরতা গুরুত্বপূর্ণ।
ধরুন আপনি দ্রুত আই / ও-র জন্য একটি ফাইল মেমরি-ম্যাপ করেন এবং সেই ফাইলটি পর্দার আড়ালে পরিবর্তিত হতে পারে (যেমন ফাইলটি আপনার স্থানীয় হার্ড ড্রাইভে নেই, তবে পরিবর্তে অন্য কম্পিউটারের মাধ্যমে নেটওয়ার্কে পরিবেশন করা হয়েছে)।
যদি আপনি অ-উদ্বায়ী বস্তুগুলিতে (উত্স কোড স্তরে) পয়েন্টারগুলির মাধ্যমে মেমরি-ম্যাপযুক্ত ফাইলের ডেটা অ্যাক্সেস করেন তবে সংকলকটির দ্বারা উত্পন্ন কোডটি আপনাকে সচেতন না করে একই তথ্য একাধিকবার আনতে পারে।
যদি সেই ডেটা পরিবর্তন হতে থাকে তবে আপনার প্রোগ্রামটি ডেটার দুটি বা আরও বেশি সংস্করণ ব্যবহার করতে পারে এবং বেমানান অবস্থায় যেতে পারে। এটি অবিশ্বাস্য অবস্থান থেকে অবিশ্বস্ত ফাইল বা ফাইল প্রসেস করা হলে এটি কেবলমাত্র প্রোগ্রামটির যুক্তিযুক্তভাবে ভুল আচরণকেই নয়, তবে এতে সুরক্ষিত সুরক্ষা গর্তকে কাজে লাগাতে পারে।
আপনি যদি সুরক্ষা সম্পর্কে চিন্তা করেন এবং আপনার উচিত, এটি বিবেচনা করার জন্য একটি গুরুত্বপূর্ণ দৃশ্য।
অস্থির মানে স্টোরেজটি যে কোনও সময় পরিবর্তিত হতে পারে এবং পরিবর্তিত হতে পারে তবে এটি ব্যবহারকারীর প্রোগ্রামের নিয়ন্ত্রণের বাইরে কিছু। এর অর্থ হ'ল আপনি যদি ভেরিয়েবলটি উল্লেখ করেন তবে প্রোগ্রামটির সর্বদা শারীরিক ঠিকানা পরীক্ষা করা উচিত (অর্থাত একটি ম্যাপযুক্ত ইনপুট ফিফো), এবং এটি ক্যাশেড উপায়ে ব্যবহার করা উচিত নয়।
উইকি সম্পর্কে সবকিছু বলে volatile
:
এবং লিনাক্স কার্নেলের ডকটি সম্পর্কে একটি দুর্দান্ত স্বরলিপি দেয় volatile
:
আমার মতে, আপনার কাছ থেকে খুব বেশি আশা করা উচিত নয় volatile
। উদাহরণস্বরূপ, নীল পিপেনব্রিন্কের সর্বাধিক ভোট দেওয়া উত্তরের উদাহরণটি দেখুন ।
আমি বলব, তার উদাহরণটি উপযুক্ত নয় volatile
। volatile
কেবলমাত্র এটির জন্য ব্যবহৃত হয়:
সংকলকটিকে দরকারী এবং পছন্দসই অপ্টিমাইজেশন করা থেকে বিরত রাখুন । এটি থ্রেড নিরাপদ, পারমাণবিক অ্যাক্সেস বা এমনকি মেমরির ক্রম সম্পর্কে কিছুই নয়।
সেই উদাহরণে:
void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isbusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}
কেবলমাত্র gadget->data = data
পূর্বে gadget->command = command
কেবল সংকলক দ্বারা সংকলিত কোডে গ্যারান্টিযুক্ত। চলমান সময়ে, প্রসেসর সম্ভবত প্রসেসরের আর্কিটেকচার সম্পর্কিত ডেটা এবং কমান্ড অ্যাসাইনমেন্টটি পুনরায় অর্ডার করে। হার্ডওয়্যারটি ভুল ডেটা পেতে পারে (ধরুন গ্যাজেটটি হার্ডওয়্যার আই / ও-তে ম্যাপ করা আছে)। ডেটা এবং কমান্ড কার্যভারের মধ্যে মেমরি বাধা প্রয়োজন
volatile
পারফরম্যান্সকে হ্রাস করছে। এটি যথেষ্ট কিনা তা হিসাবে এটি সিস্টেমের অন্যান্য বিষয়গুলির উপর নির্ভর করবে যা প্রোগ্রামার সংকলকটির চেয়ে বেশি জানতে পারে। অন্যদিকে, যদি কোনও প্রসেসর গ্যারান্টি দেয় যে একটি নির্দিষ্ট ঠিকানায় লেখার জন্য নির্দেশ সিপিইউ ক্যাশে ফ্লাশ করবে তবে একটি সংকলক সিপিইউ সম্পর্কে রেজিস্টার-ক্যাশেড ভেরিয়েবলগুলি ফ্লাশ করার কোনও উপায় সরবরাহ করে না, ক্যাশে ফ্লাশ করা অকেজো হবে।
ডেনিস রিচি ডিজাইন করা ভাষায়, যে কোনও বস্তুর অ্যাক্সেস, স্বয়ংক্রিয় বস্তুগুলি ছাড়া যাদের ঠিকানা নেওয়া হয়নি, অন্যরকম অ্যাক্সেসের সাথে আচরণ করবে যেমন এটি বস্তুর ঠিকানা গণনা করে এবং সেই ঠিকানায় স্টোরেজটি পড়ে বা লিখেছিল wrote এটি ভাষাটিকে খুব শক্তিশালী করেছে, তবে মারাত্মকভাবে সীমিত অপ্টিমাইজেশনের সুযোগ তৈরি করেছে।
যদিও কোনও কোয়ালিফায়ার যুক্ত করা সম্ভব হয়েছিল যা একটি কম্পাইলারকে এই ধারণাটি দেওয়ার জন্য আমন্ত্রণ জানাত যে কোনও নির্দিষ্ট বিষয়টিকে অদ্ভুত উপায়ে পরিবর্তন করা হবে না, তবে এই ধরনের অনুমিতি সি প্রোগ্রামগুলির বৃহত সংখ্যাগুলির জন্য উপযুক্ত হবে এবং এটির সমস্ত অবজেক্টের জন্য একটি যোগ্যতা যুক্ত করা অবৈধ ছিল যার জন্য এই ধরনের অনুমান করা উপযুক্ত হবে। অন্যদিকে, কিছু প্রোগ্রামের জন্য এমন কিছু অবজেক্ট ব্যবহার করা দরকার যার জন্য এই ধরনের অনুমানটি ধারণ করে না। এই সমস্যাটি সমাধান করার জন্য, স্ট্যান্ডার্ড বলেছে যে সংকলকগণ ঘোষণা করতে পারে না যে বস্তুগুলি volatile
সংকলকটির নিয়ন্ত্রণের বাইরে এমনভাবে তাদের মান পর্যবেক্ষণ বা পরিবর্তিত হবে না বা যুক্তিসঙ্গত সংকলকের বোঝার বাইরে থাকবে ass
যেহেতু বিভিন্ন প্ল্যাটফর্মের বিভিন্ন উপায়ে কোনও সংকলকের নিয়ন্ত্রণের বাইরে অবজেক্টগুলি পর্যবেক্ষণ বা সংশোধন করা যেতে পারে, তাই উপযুক্ত যে এই প্ল্যাটফর্মগুলির জন্য মানের সংকলকগুলি volatile
শব্দার্থবিজ্ঞানের সঠিক হ্যান্ডলিংয়ের ক্ষেত্রে পৃথক হওয়া উচিত । দুর্ভাগ্যক্রমে, স্ট্যান্ডার্ডটি পরামর্শ দিতে ব্যর্থ হয়েছে যে কোনও প্ল্যাটফর্মের নিম্ন-স্তরের প্রোগ্রামিংয়ের উদ্দেশ্যে তৈরি মানের সংকলকগুলি এমনভাবে পরিচালনা volatile
করতে হবে যা সেই প্ল্যাটফর্মে কোনও নির্দিষ্ট পঠন / লেখার ক্রিয়াকলাপের যে কোনও এবং সমস্ত প্রাসঙ্গিক প্রভাবকে স্বীকৃতি দেয় many সুতরাং যে উপায়ে ব্যাকগ্রাউন্ড I / O এর মতো জিনিসগুলি এমনভাবে প্রক্রিয়া করা শক্ত করে তোলে যা দক্ষ তবে কিন্তু সংকলক "অপ্টিমাইজেশন" দ্বারা ভাঙা যায় না।
যথাযথভাবে এখানে অনেকের দ্বারা প্রস্তাবিত হিসাবে, অস্থায়ী কীওয়ার্ডের জনপ্রিয় ব্যবহারটি হ'ল ভোল্টাইল ভেরিয়েবলের অপ্টিমাইজেশন এড়িয়ে যাওয়া।
সবচেয়ে ভাল সুবিধা যা মনে আসে এবং অস্থিরতা সম্পর্কে পড়ার পরে উল্লেখযোগ্য তা হ'ল - এর ক্ষেত্রে পরিবর্তনশীলটির পিছনে ঘোরানো রোধ করাlongjmp
। একটি স্থানীয় নয়।
এটার মানে কি?
এর সহজ অর্থ হ'ল আপনি অনাবন্ধিক স্ট্যাক করার পরে শেষ মানটি বজায় থাকবে পূর্ববর্তী কিছু স্ট্যাক ফ্রেমে ফিরে আসার জন্য ; সাধারণত কিছু ভুল পরিস্থিতিতে।
যেহেতু এটি এই প্রশ্নের আওতার বাইরে থাকবে, আমি setjmp/longjmp
এখানে বিশদ বিবরণে যাচ্ছি না , তবে এটি সম্পর্কে পড়া ভাল; এবং কীভাবে অস্থিরতা বৈশিষ্ট্যটি সর্বশেষ মান ধরে রাখতে ব্যবহার করা যেতে পারে।