সি স্ট্যান্ডার্ডটির জন্য মেশিনের ঠিকানা শূন্যের নাল পয়েন্টার থাকা দরকার না। তবুও, 0
একটি পয়েন্টার মানের কাছে ধ্রুবক NULL
castালাইয়ের ফলে অবশ্যই একটি পয়েন্টার (§6.3.2.3 / 3) হওয়া উচিত এবং নুল পয়েন্টারটিকে বুলিয়ান হিসাবে মূল্যায়ন করা অবশ্যই মিথ্যা হতে পারে। এটি কিছুক্ষণ বিশ্রী যদি সত্যিই হতে পারে না একটি শূন্য ঠিকানা চান, এবং NULL
শূন্য ঠিকানা নয়।
তবুও, সংকলক এবং স্ট্যান্ডার্ড লাইব্রেরিতে (ভারী) পরিবর্তনগুলি সহ, স্ট্যান্ডার্ড লাইব্রেরিতে NULL
এখনও কঠোরভাবে অনুসারী থাকা অবস্থায় বিকল্প বিট প্যাটার্ন দ্বারা প্রতিনিধিত্ব করা অসম্ভব নয় । এটা না কেবল সংজ্ঞা পরিবর্তন করতে যথেষ্ট NULL
যেমন তারপর অবশ্য নিজেই NULL
সত্যতে মূল্যায়ন করবেন।
বিশেষত, আপনার প্রয়োজন:
- পয়েন্টারগুলিতে অ্যাসাইনমেন্টে আক্ষরিক শূন্যগুলির জন্য বিন্যাস করুন (বা পয়েন্টারগুলিতে কাস্ট করুন) যেমন কিছু অন্য যাদু মান হিসাবে রূপান্তরিত করতে
-1
।
0
পরিবর্তে ম্যাজিক মান পরীক্ষা করতে পয়েন্টার এবং ধ্রুবক পূর্ণসংখ্যার মধ্যে সমতা পরীক্ষার ব্যবস্থা করুন (.5§.§.৯ /))
- শূন্যের জন্য যাচাই করার পরিবর্তে যাদু মানটির সাম্যতা পরীক্ষা করার জন্য বুলিয়ান হিসাবে একটি পয়েন্টার ধরণের মূল্যায়ন করা হয় এমন সমস্ত প্রসঙ্গে বিন্যাস করুন। এটি সাম্যতা পরীক্ষার শব্দার্থকগুলি থেকে অনুসরণ করে তবে সংকলকটি অভ্যন্তরীণভাবে এটি ভিন্নভাবে প্রয়োগ করতে পারে। §6.5.13 / 3, §6.5.14 / 3, §6.5.15 / 4, §6.5.3.3 / 5, §6.8.4.1 / 2, .86.8.5 / 4 দেখুন
- ক্যাফে হিসাবে উল্লেখ করা হয়েছে, নতুন নাল পয়েন্টার উপস্থাপনা প্রতিবিম্বিত করতে স্ট্যাটিক অবজেক্টস (§6.7.8 / 10) এবং আংশিক যৌগিক প্রারম্ভক (.76.7.8 / 21) আরম্ভের জন্য শব্দার্থকে আপডেট করুন।
- সত্য ঠিকানা শূন্য অ্যাক্সেস করার জন্য একটি বিকল্প উপায় তৈরি করুন।
কিছু জিনিস আপনার পরিচালনা করতে হবে না । উদাহরণ স্বরূপ:
int x = 0;
void *p = (void*)x;
এর পরে, p
নাল পয়েন্টার হওয়ার নিশ্চয়তা নেই। কেবল ধ্রুবক অ্যাসাইনমেন্টগুলি পরিচালনা করা প্রয়োজন (এটি সত্যিকারের শূন্যের অ্যাক্সেসের জন্য একটি ভাল পদ্ধতির)। অনুরূপভাবে:
int x = 0;
assert(x == (void*)0); // CAN BE FALSE
এছাড়াও:
void *p = NULL;
int x = (int)p;
x
হতে গ্যারান্টিযুক্ত হয় না 0
।
সংক্ষেপে, এই খুব শর্তটি স্পষ্টতই সি ভাষা কমিটি বিবেচনা করেছিল এবং যারা NULL এর জন্য বিকল্প উপস্থাপনা বেছে নেবে তাদের জন্য বিবেচনা করা হয়েছিল। আপনাকে এখন যা করতে হবে তা হ'ল আপনার সংকলকটিতে বড় পরিবর্তন আনতে হবে এবং আরে প্রেস্টো আপনি শেষ করেছেন :)
পার্শ্ব নোট হিসাবে, সংকলক যথাযথ হওয়ার আগে উত্স কোড রূপান্তর পর্যায়ে এই পরিবর্তনগুলি প্রয়োগ করা সম্ভব। এটি হ'ল প্রিপ্রোসেসর -> সংকলক -> এসেইম্বেলার -> লিংকারের স্বাভাবিক প্রবাহের পরিবর্তে আপনি একটি প্রিপ্রসেসর -> নুল ট্রান্সফর্মেশন -> সংকলক -> এস্যাসেবলার -> লিংক যুক্ত করতে পারেন। তারপরে আপনি যেমন রূপান্তর করতে পারেন:
p = 0;
if (p) { ... }
/* becomes */
p = (void*)-1;
if ((void*)(p) != (void*)(-1)) { ... }
এর জন্য একটি সম্পূর্ণ সি পার্সার প্রয়োজন হবে, পাশাপাশি টাইপডেফস এবং ভেরিয়েবলের ঘোষণার বিশ্লেষণ করতে হবে যা চিহ্নিতকারীদের সাথে সম্পর্কিত কিনা তা নির্ধারণ করতে। তবে এটি করে আপনি সংকলকটির কোড জেনারেশনের অংশগুলিতে যথাযথ পরিবর্তন করতে পারবেন না। ঝাঁকুনি এটি বাস্তবায়নের জন্য দরকারী হতে পারে - আমি বুঝতে পারি যে এটি এই জাতীয় রূপান্তরকে সামনে রেখে ডিজাইন করা হয়েছিল। আপনার সম্ভবত অবশ্যই স্ট্যান্ডার্ড লাইব্রেরিতে অবশ্যই পরিবর্তন করা দরকার।
mprotect
সুরক্ষিত করতে। বা, যদি প্ল্যাটফর্মটির কোনও এএসএলআর বা মত না থাকে তবে প্ল্যাটফর্মের শারীরিক মেমরির বাইরে ঠিকানাগুলি। শুভকামনা।