এই জাতীয় কোডের অনেক সুবিধা থাকতে পারে, তবে দুর্ভাগ্যক্রমে সি স্ট্যান্ডার্ডটি এটি সুবিধার জন্য লেখা হয়নি। সংকলকগণ historতিহাসিকভাবে স্ট্যান্ডার্ড সি দ্বারা প্রয়োজনীয় কোডের চেয়ে বেশি পরিষ্কারভাবে এই জাতীয় কোড লিখতে সক্ষম করেছিল তার চেয়ে কার্যকর আচরণগত গ্যারান্টি দিয়েছিল, তবে সংযোজকরা ইদানীং অপ্টিমাইজেশনের নামে এই ধরনের গ্যারান্টিটি প্রত্যাহার শুরু করেছেন।
সর্বাধিক উল্লেখযোগ্যভাবে, অনেক সি সংকলক historতিহাসিকভাবে গ্যারান্টিযুক্ত (ডকুমেন্টেশন না থাকলে ডিজাইনের মাধ্যমে) যে দুটি কাঠামোর ধরণের একই প্রাথমিক ক্রম থাকে, তবে উভয় প্রকারের পয়েন্টারটি সেই সাধারণ ক্রমের সদস্যদের অ্যাক্সেস করতে ব্যবহার করতে পারে, এমনকি প্রকারগুলি সম্পর্কযুক্ত না থাকলেও, এবং আরও একটি সাধারণ প্রাথমিক ক্রম স্থাপনের উদ্দেশ্যে কাঠামোর সমস্ত পয়েন্টার সমান। এই জাতীয় আচরণের কোডটি কোডের চেয়ে অনেক বেশি ক্লিনার এবং টাইপ-নিরাপদ হতে পারে যা না হয় তবে দুর্ভাগ্যক্রমে যদিও স্ট্যান্ডার্ডের প্রয়োজন হয় যে সাধারণ প্রাথমিক ক্রমগুলি ভাগ করে নেওয়ার কাঠামোগুলি একইভাবে নির্ধারণ করা উচিত, এটি কোডটি আসলে ব্যবহার থেকে নিষেধ করে অন্য প্রারম্ভিক ক্রম অ্যাক্সেস করতে এক প্রকারের পয়েন্টার।
ফলস্বরূপ, আপনি যদি সিটিতে অবজেক্ট-ভিত্তিক কোড লিখতে চান, আপনাকে সি এর পয়েন্টার-টাইপ বিধি মেনে চলার জন্য প্রচুর হুপ থেকে ঝাঁপ দেওয়ার সিদ্ধান্ত নিতে হবে (এবং এই সিদ্ধান্তটি শীঘ্রই করা উচিত) have আধুনিক সংকলকগুলি যদি কিছু পিছলে যায় তবে অবাস্তব কোড জেনারেট করে, এমনকি পুরানো সংকলকগণ কোড হিসাবে উদ্দিষ্ট হিসাবে কাজ করে যা অন্যথায় একটি প্রয়োজনীয়তা নথি করে যে কোডটি কেবলমাত্র সেই পুরানো শৈলীর পয়েন্টার আচরণকে সমর্থন করার জন্য কনফিগার করা সংকলকগুলির সাথে ব্যবহারযোগ্য হবে (যেমন ব্যবহার করে একটি "-ফনো-কড়া-আলিয়াজিং") কিছু লোক "-ফনো-কড়া-আলিয়াজিং" কে মন্দ হিসাবে বিবেচনা করে তবে আমি পরামর্শ দেব যে "-ফনো-কড়া-আলিয়াজিং" সিটিকে এমন একটি ভাষা হিসাবে ভাবা আরও কার্যকর "স্ট্যান্ডার্ড" সি এর চেয়ে কয়েকটি উদ্দেশ্যে বৃহত্তর অর্থশক্তি সরবরাহ করে,তবে অপ্টিমাইজেশনের ব্যয়ে যা অন্য কিছু উদ্দেশ্যে গুরুত্বপূর্ণ হতে পারে।
উদাহরণস্বরূপ, traditionalতিহ্যবাহী সংকলকগুলিতে, historicalতিহাসিক সংকলকগুলি নিম্নলিখিত কোডটি ব্যাখ্যা করবেন:
struct pair { int i1,i2; };
struct trio { int i1,i2,i3; };
void hey(struct pair *p, struct trio *t)
{
p->i1++;
t->i1^=1;
p->i1--;
t->i1^=1;
}
যাতে নিম্নলিখিত পদক্ষেপগুলি যথাযথভাবে সম্পাদন করা হয়: প্রথম সদস্যের বর্ধিতকরণ, প্রথম সদস্যের *p
সর্বনিম্ন বিট পরিপূরক *t
, তারপরে প্রথম সদস্যের হ্রাস *p
, এবং প্রথম সদস্যের সর্বনিম্ন বিট পরিপূরক *t
। আধুনিক সংকলকগুলি কোনও ফ্যাশনে ক্রিয়াকলাপগুলি পুনরায় সাজিয়ে তুলবে যা কোন কোডে আরও কার্যকর হবে p
এবং t
বিভিন্ন বস্তু সনাক্ত করতে পারে তবে তারা যদি তা না করে তবে আচরণটি পরিবর্তন করবে।
এই উদাহরণটিতে অবশ্যই ইচ্ছাকৃতভাবে কল্পিত হয়, এবং যা এক্সেস সদস্যরা আরেক ধরনের সাধারণ প্রাথমিক ক্রম অংশ হবে এক ধরনের একটি পয়েন্টার ব্যবহার অনুশীলন কোডে সাধারণত কাজ , তবে দুর্ভাগ্যক্রমে যেহেতু এই জাতীয় কোডটি কখন ব্যর্থ হতে পারে তা জানার কোনও উপায় নেই টাইপ-ভিত্তিক আলিয়াসিং বিশ্লেষণ অক্ষম করে ব্যতীত নিরাপদে এটিকে ব্যবহার করা সম্ভব নয়।
কিছুটা স্বতন্ত্র প্রকারের কাছে দুটি পয়েন্টার অদলবদলের মতো কিছু করার জন্য কোনও ফাংশন লিখতে চাইলে কিছুটা কম সংঘাতযুক্ত উদাহরণ দেখা দেয়। "1990 এর সি" সংকলকের বিশাল সংখ্যায়, এটি এর মাধ্যমে সম্পন্ন হতে পারে:
void swap_pointers(void **p1, void **p2)
{
void *temp = *p1;
*p1 = *p2;
*p2 = temp;
}
স্ট্যান্ডার্ড সি তে তবে একটি ব্যবহার করতে হবে:
#include "string.h"
#include "stdlib.h"
void swap_pointers2(void **p1, void **p2)
{
void **temp = malloc(sizeof (void*));
memcpy(temp, p1, sizeof (void*));
memcpy(p1, p2, sizeof (void*));
memcpy(p2, temp, sizeof (void*));
free(temp);
}
যদি *p2
বরাদ্দকৃত স্টোরেজে রাখা হয় এবং অস্থায়ী পয়েন্টারটি বরাদ্দকৃত স্টোরেজে না রাখা হয় তবে কার্যকর ধরণের *p2
অস্থায়ী পয়েন্টার এবং কোডটি *p2
কোনও ধরণের অস্থায়ী পয়েন্টারের সাথে মেলে না এমন কোনও রূপে ব্যবহার করার চেষ্টা করে টাইপ অনির্ধারিত আচরণ শুরু করবে। এটি অত্যন্ত অসম্ভাব্য যে কোনও সংকলকটি এ জাতীয় জিনিসটি লক্ষ্য করবে, তবে যেহেতু আধুনিক সংকলক দর্শনের প্রয়োজন হয় যে প্রোগ্রামাররা কোনও মূল্যে অপরিজ্ঞাত আচরণ এড়ানো যায়, তাই বরাদ্দকৃত স্টোরেজ ব্যবহার না করে উপরের কোডটি লেখার কোনও নিরাপদ উপায় আমি ভাবতে পারি না ।