কোনও প্রদত্ত প্রোগ্রামে এই জাতীয় বক্তব্যটির অস্তিত্বের অর্থ কি পুরো প্রোগ্রামটি অনির্ধারিত হয়েছে বা নিয়ন্ত্রণ প্রবাহ এই বিবৃতিতে আঘাতের পরে কেবল আচরণটি অপরিজ্ঞাত হয়ে যায়?
না। প্রথম অবস্থাটি খুব শক্ত এবং দ্বিতীয়টি খুব দুর্বল।
অবজেক্ট অ্যাক্সেস কখনও কখনও ক্রমযুক্ত হয়, কিন্তু মান সময়ের বাইরে প্রোগ্রামের আচরণ বর্ণনা করে। ড্যানভিল ইতিমধ্যে উদ্ধৃত:
যদি এই জাতীয় নির্বাহের কোনও অপরিজ্ঞাত অপারেশন থাকে তবে এই আন্তর্জাতিক স্ট্যান্ডার্ডটি সেই ইনপুট দিয়ে সেই প্রোগ্রামটি সম্পাদন করে এমন বাস্তবায়নের কোনও প্রয়োজনীয়তা রাখে না (এমনকি প্রথম অপরিবর্তিত অপারেশন পূর্ববর্তী অপারেশনগুলির ক্ষেত্রেও নয়)
এটি ব্যাখ্যা করা যেতে পারে:
যদি প্রোগ্রামটির সম্পাদনটি অনির্ধারিত আচরণের ফলন করে তবে পুরো প্রোগ্রামটিরই নির্ধারিত আচরণ থাকে।
সুতরাং, ইউবির সাথে একটি অপ্রাপ্য বক্তব্য প্রোগ্রামটিকে ইউবি দেয় না। একটি पहुंचযোগ্য বক্তব্য যা (ইনপুটগুলির মানগুলির কারণে) কখনই পৌঁছায় না, প্রোগ্রামটিকে ইউবি দেয় না। এজন্য আপনার প্রথম অবস্থাটি খুব শক্ত।
এখন, সংকলকটি সাধারণভাবে বলতে পারে না যে কীভাবে ইউবি রয়েছে। সুতরাং অপটিমাইজারকে সম্ভাব্য ইউবি দিয়ে পুনরায় অর্ডার করার অনুমতি দেওয়ার জন্য যা তাদের আচরণটি সংজ্ঞায়িত করা উচিত যদি পুনরায় বিবেচনাযোগ্য হয়, তবে ইউবিটিকে "সময়মতো ফিরে যেতে" অনুমতি দেওয়া এবং পূর্ববর্তী সিকোয়েন্স পয়েন্টের আগে ভুল হওয়া উচিত (বা সিতে ++ 11 টি পরিভাষা, UB এর জন্য UB জিনিসটির আগে ধারাবাহিকভাবে থাকা জিনিসগুলিকে প্রভাবিত করে)। সুতরাং আপনার দ্বিতীয় অবস্থা খুব দুর্বল।
এটির একটি প্রধান উদাহরণ হ'ল যখন অপ্টিমাইজার কঠোরভাবে এলিয়াসিংয়ের উপর নির্ভর করে। কঠোর অ্যালাইজিং বিধিগুলির পুরো বিন্দুটি হ'ল সংকলককে পুনরায় অর্ডার ক্রিয়াকলাপের অনুমতি দেওয়া যা যদি বৈধভাবে উত্তর ওরফে পয়েন্টার একই মেমরির পক্ষে পুনরায় অর্ডার করা যায় না could সুতরাং আপনি যদি অবৈধভাবে এলিয়াসিং পয়েন্টার ব্যবহার করেন এবং ইউবি ঘটে থাকে তবে এটি সহজেই ইউবি স্টেটমেন্টের "আগে" একটি বিবৃতিকে প্রভাবিত করতে পারে। যতদূর অ্যাবস্ট্রাক্ট মেশিনটি উদ্বিগ্ন ইউবির বিবৃতিটি এখনও কার্যকর করা হয়নি। যতক্ষণ না আসল অবজেক্ট কোড সম্পর্কিত, এটি আংশিক বা পুরোপুরি কার্যকর করা হয়েছে। তবে স্ট্যান্ডার্ডটি অপ্টিমাইজারের বিবৃতিগুলি পুনরায় অর্ডার করার অর্থ কী, বা ইউবির ক্ষেত্রে এর কী কী প্রভাব ফেলবে সে সম্পর্কে বিস্তারিত জানার চেষ্টা করে না। এটি কেবল বাস্তবায়নের লাইসেন্সটিকে খুশি হওয়ার সাথে সাথে ভুল হতে দেয়।
আপনি এটি হিসাবে ভাবতে পারেন, "ইউবিতে একটি টাইম মেশিন রয়েছে"।
বিশেষত আপনার উদাহরণগুলির উত্তর দিতে:
- আচরণটি কেবল 3 টি পড়লে অপরিজ্ঞাত হয়।
- সংযোগকারীরা কোডটিকে মৃত হিসাবে নির্মূল করতে এবং করতে পারে যদি একটি প্রাথমিক ব্লকে কোনও অপারেশন নির্দিষ্ট না করে নির্দিষ্ট করা থাকে contains এগুলিকে অনুমতি দেওয়া হয়েছে (এবং আমি অনুমান করছি) যেগুলি কোনও প্রাথমিক ব্লক নয় তবে যেখানে সমস্ত শাখাগুলি ইউবির দিকে পরিচালিত করে। এই উদাহরণটি কোনও প্রার্থী নয় যদি না
PrintToConsole(3)
কোনওভাবে ফিরে আসার বিষয়ে নিশ্চিত হন। এটি একটি ব্যতিক্রম বা যাই হোক না কেন নিক্ষেপ করতে পারে।
আপনার দ্বিতীয়টির মতো একই উদাহরণটি হ'ল জিসিসি বিকল্প -fdelete-null-pointer-checks
, যা এই জাতীয় কোড নিতে পারে (আমি এই নির্দিষ্ট উদাহরণটি পরীক্ষা করে দেখিনি, এটি সাধারণ ধারণার উদাহরণস্বরূপ বিবেচনা করুন):
void foo(int *p) {
if (p) *p = 3;
std::cout << *p << '\n';
}
এবং এটিকে পরিবর্তন করুন:
*p = 3;
std::cout << "3\n";
কেন? কারণ যদি p
এটি নাল হয় তবে কোডটি যাহাই হউক না কেন ইউবি রয়েছে, তাই সংকলকটি ধরে নিতে পারে এটি নাল নয় এবং সেই অনুসারে অনুকূলিত। লিনাক্স কার্নেলটি এটিকে ছাপিয়ে গেছে ( https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-1897 ) মূলত কারণ এটি এমন একটি মোডে পরিচালনা করে যেখানে নাল পয়েন্টারকে অবজ্ঞা করার কথা নয় ইউবি হোন, এটির সাহায্যে কার্নেল হ্যান্ডেল করতে পারে এমন একটি সংজ্ঞায়িত হার্ডওয়্যার ব্যতিক্রম হবে। যখন অপ্টিমাইজেশন সক্ষম করা থাকে, তখন গিসি এর -fno-delete-null-pointer-checks
মান-এর বাইরে গ্যারান্টি সরবরাহ করার জন্য ব্যবহার প্রয়োজন ।
পিএস এই প্রশ্নের বাস্তবিক উত্তর "কখনই অপরিবর্তিত আচরণটি ধর্মঘট করে?" "আপনি দিনের উদ্দেশ্যে যাত্রা করার 10 মিনিট আগে"।