সি ++ এ পরিবর্তনীয় বনাম পরিবর্তনীয়


86

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

অনেক ধন্যবাদ.

উত্তর:


113

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


13
volatileসিপিইউ জড়িত না এমন প্রক্রিয়াগুলি দ্বারা অবজেক্টগুলিও পরিবর্তন করা যেতে পারে। উদাহরণস্বরূপ, একটি যোগাযোগ পেরিফেরিয়াল বাইটস প্রাপ্ত রেজিস্ট্রেশন একটি বাইট প্রাপ্তির পরে নিজেকে বাড়িয়ে তুলতে পারে (এবং এটি এমনকি একটি বাধা সৃষ্টি করতে পারে)। আরেকটি উদাহরণ হল পেরিফেরিয়াল স্থগিত-বিঘ্নিত পতাকা নিবন্ধগুলি।
মাইক ডিসিমোন

56
এছাড়াও, volatileকেবলমাত্র এটির অর্থ এই নয় যে কম্পাইলারটির জ্ঞানের বাইরে অবজেক্টটি পরিবর্তন হতে পারে - এর অর্থ হ'ল লেখকগুলি অকেজো বলে মনে হলেও অবজেক্টকে লেখার সংকলক দ্বারা মুছে ফেলা যায় না। উদাহরণস্বরূপ: x = 1; x = 0; যদি xঅস্থির হয় তবে সংকলকটিকে উভয় রাইটিং অপারেশন নির্গত করতে হবে (যা হার্ডওয়্যার স্তরে উল্লেখযোগ্য হতে পারে)। যাইহোক, একটি অ-উদ্বায়ী বস্তুর জন্য, সংকলকটি 1কখনও ব্যবহার করা হয়নি বলে লেখার বিষয়ে বিরক্ত না করা বেছে নিতে পারে ।
মাইকেল

15
একটি বস্তু উভয় চিহ্নিত করা যেতে পারে constএবং volatile! আপনি বস্তুটি পরিবর্তন করতে পারবেন না, তবে এটি আপনার পিছনে পিছনে পরিবর্তন করা যেতে পারে।
সিটিমা্যাকউসার

4
@ পরিচালক: সাধারণ পরিস্থিতি হ'ল একটি হার্ডওয়্যার ডিভাইস রেজিস্ট্রারে লেখার জন্য।
মাইকেল বুড়

4
@ পরিচালক আপনি যাক একটি এলইডি এর স্থিতি নিয়ন্ত্রণ করছেন। 0 টি এটি বন্ধ করে লিখুন, 1 টি এটি চালু করে write কিছু ত্রুটির স্থিতি যোগাযোগের জন্য যদি আমার এলইডি ফ্ল্যাশ করা প্রয়োজন তবে সংকলক শেষের লেখক ব্যতীত সমস্ত লেখাকেই অনুকূলিত করার সিদ্ধান্ত নিয়েছে, যেহেতু কোনও মানই ব্যবহার করা হচ্ছে না, তবে এলইডি কখনই জ্বলজ্বল হয় না এবং আমার যে আচরণটি ইচ্ছা হয় তা উপলব্ধি হয় না ।
ইহানেই

28

mutable: পরিবর্তনীয় কীওয়ার্ডটি কোনও সংকোচনকারী কনট স্টেটমেন্টকে ওভাররাইড করে। কোনও কনস্টের অবজেক্টের একজন মিউটেবল সদস্যকে পরিবর্তন করা যেতে পারে।

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

উৎস


আপনি বলেছিলেন Volatile should be used with variables whose value can change in unexpected waysযে আমরা এলোমেলোভাবে এটি ব্যবহার করতে পছন্দ করব?
আসিফ মোশতাক

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

22

তারা অবশ্যই একই জিনিস নয়। কনস্টের সাথে পারস্পরিক পারস্পরিক যোগাযোগ। আপনার যদি কনস্ট পয়েন্টার থাকে তবে আপনি সাধারনত সদস্য পরিবর্তন করতে পারবেন না। মিউটেবল সেই নিয়মের ব্যতিক্রম সরবরাহ করে।

অন্যদিকে, উদ্বায়ী প্রোগ্রামটি দ্বারা পরিবর্তনগুলির সাথে সম্পূর্ণ সম্পর্কযুক্ত নয়। এর অর্থ হ'ল সংকলকটির নিয়ন্ত্রণের বাইরে স্মৃতির মেমরিটি পরিবর্তিত হতে পারে, সুতরাং কম্পাইলারটি প্রতিবার মেমরি ঠিকানাটি পড়তে বা লিখতে হয় এবং কোনও রেজিস্টারে সামগ্রীটি ক্যাশে করতে পারে না।


"অন্যদিকে, উদ্বায়ী, প্রোগ্রামের পরিবর্তনের সাথে পুরোপুরি সম্পর্কিত নয় ..." - হুঁ, সদস্যকে অস্থির করে তুলুন এবং সংকলনের সময় কী কী বিরতি ঘটে তা দেখুন। সত্যের পরে অস্থির যুক্ত করার চেষ্টা করা সত্যের পরে কনস্ট যুক্ত করার চেষ্টা করার মতো ... বেদনাদায়ক।
jww

@jww: প্রোগ্রামটি দ্বারা রচিত এটি সম্পূর্ণরূপে সম্পর্কিত নয়। আপনি টাইপের কোনও অবজেক্টের ঠিকানা নিতে পারেন Tএবং এটি একটিতে সঞ্চয় করতে const T*পারেন এবং এটি থেকে পড়তে পারেন। আপনি যদি সেই বস্তুটি তৈরি করেন তবে volatileএর ঠিকানাটি সংরক্ষণ করা const T*ব্যর্থ হবে, যদিও আপনি কখনও লেখার চেষ্টা করছেন না। volatileএবং প্রোগ্রাম কোড থেকে পরিবর্তনগুলি / পরিবর্তনগুলি / মেমরির লেখাগুলি সম্পূর্ণ orthogonal।
বেন ভয়েগট

17

পার্থক্যটি বিবেচনা করার একটি অশোধিত কিন্তু কার্যকর উপায় হ'ল:

  • সংকলক জানে যখন কোনও পরিবর্তনীয় অবজেক্ট পরিবর্তন হয়।
  • সংকলক জানতে পারে না কখন একটি অস্থির বস্তু পরিবর্তন হয়।

4
সেই শিরাতে: volatileবাইটস_প্রাপ্ত, mutableরেফারেন্স_কাউন্ট।
মাইক ডিসিমোন

11

চিহ্নিত ভেরিয়েবল mutableঘোষিত পদ্ধতিতে এটি পরিবর্তন করার অনুমতি দেয় const

চিহ্নিত একটি ভেরিয়েবল volatileকম্পাইলারকে বলেছে যে আপনার কোডটি যতবার এটি বলবে ততবার অবশ্যই ভেরিয়েবলটি পড়তে / লিখতে হবে (যেমন এটি ভেরিয়েবলের অ্যাক্সেসগুলি অপ্টিমাইজ করতে পারে না)।


4

আমি যোগ করতে চাই যে মাল্টিথ্রেডিং অ্যাপ্লিকেশনগুলির সাথে ডিল করার সময় অস্থিরতাও খুব কার্যকর। যেমন আপনার মূল থ্রেড (যেখানে প্রধান () থাকে and এবং আপনি একটি কর্মী থ্রেড রেখেছিলেন যা একটি স্পর্শযোগ্য "অ্যাপ্লিকেশন_রানিং" সত্য হলেও স্পিনিং করে রাখে। প্রধান () "app_running" সত্য বা মিথ্যা কিনা তা নিয়ন্ত্রণ করে, সুতরাং যদি আপনি "অ্যাপ_রানিং" ঘোষণায় অস্থির গুণাবলী যুক্ত না করেন, যদি সংকলক গৌণ থ্রেড দ্বারা চালিত কোডটিতে "app_running" এর অ্যাক্সেসকে অনুকূল করে, প্রধান ( ) "app_running" কে ভুয়াতে পরিবর্তন করতে পারে তবে দ্বিতীয় থ্রেড চলতে থাকবে কারণ মানটি ক্যাশে হয়েছে। আমি লিনাক্স এবং ভিজুয়ালসি ++ তে জিসিসি ব্যবহার করে একই আচরণ দেখেছি। "অ্যাপ_রানিং" ঘোষণায় একটি "অস্থির" বৈশিষ্ট্য সমস্যার সমাধান করেছে। সুতরাং,


4
না! এটি একটি সাধারণ ভুল বোঝাবুঝি। সি ++ 11 এবং C11 এই কাজের জন্য atomics চালু stackoverflow.com/questions/8819095/...
KristianR
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.