অতিরিক্ত এফফ্লিয়াস কনস্টের কোনও এপিআই স্ট্যান্ড পয়েন্ট থেকে খারাপ:
কলার বা এপিআই ব্যবহারকারীর কাছে কোনও অর্থবহ প্রতিশ্রুতি না দেওয়ার সময় আপনার এপিআইতে মান ব্যঙ্গ করে এমন আন্তঃজনিত ধরণের পরামিতিগুলির জন্য আপনার কোডগুলিতে অতিরিক্ত অতিরিক্ত ত্রুটিযুক্ত কনস্টের স্থাপন করা (এটি কেবলমাত্র প্রয়োগকে বাধা দেয়)।
যখন প্রয়োজন হয় না তখন একটি এপিআইতে অনেকগুলি 'কনস্ট' হ'ল " কান্নার নেকড়ে " এর মতো, অবশেষে লোকেরা 'কনস্ট' উপেক্ষা করতে শুরু করবে কারণ এটি পুরো জায়গা জুড়ে এবং এর অর্থ বেশিরভাগ সময়ই কিছুই নয়।
এপিআই-তে অতিরিক্ত কনসটের কাছে "কমানো বিজ্ঞাপন অ্যাবসার্ডাম" যুক্তি এই প্রথম দুটি পয়েন্টের জন্য ভাল তবে যদি আরও কনস্ট প্যারামিটারগুলি ভাল হয় তবে প্রতিটি যুক্তি যার সাথে এটির উপর একটি কনস্ট থাকতে পারে, এটির একটি কনস্ট থাকতে হবে। আসলে, যদি এটি সত্যিই ভাল ছিল তবে আপনি প্যারামিটারগুলি পরিবর্তন করতে চাইলে আপনি কেবল পরামিতিগুলির জন্য ডিফল্ট হতে চান এবং "পরিবর্তনীয়" এর মতো একটি কীওয়ার্ড রাখতে চান।
সুতরাং আসুন আমরা যেভাবেই পারি কনটেড করার চেষ্টা করি:
void mungerum(char * buffer, const char * mask, int count);
void mungerum(char * const buffer, const char * const mask, const int count);
উপরের কোড লাইন বিবেচনা করুন। ঘোষণাপত্রটি কেবল আরও বিশৃঙ্খল এবং দীর্ঘতর এবং পড়া আরও কঠিন নয় তবে চারটি 'কনস্ট' কীওয়ার্ডের মধ্যে তিনটি এপিআই ব্যবহারকারী নিরাপদে উপেক্ষা করতে পারে। তবে 'কনস্ট' অতিরিক্ত ব্যবহারের ফলে দ্বিতীয় লাইনটি সম্ভাব্য ঝুঁকিপূর্ণ হয়ে উঠেছে !
কেন?
প্রথম প্যারামিটারের একটি দ্রুত ভুল পড়া char * const buffer
আপনাকে মনে করতে পারে যে এটি ডেটা বাফারে যে মেমোরিটিকে পাস করেছে তা মেমরিটি পরিবর্তন করবে না - তবে, এটি সত্য নয়! অনাবৃত 'কনস্ট' আপনার এপিআই সম্পর্কে বিপজ্জনক এবং ভুল অনুমানের দিকে পরিচালিত করতে পারে যখন স্ক্যান করা হয় বা দ্রুত অপ্রচারিত হয়।
অতিরিক্ত প্রয়োগকারী কোনও কোড বাস্তবায়ন স্ট্যান্ড-পয়েন্ট থেকে খারাপ are
#if FLEXIBLE_IMPLEMENTATION
#define SUPERFLUOUS_CONST
#else
#define SUPERFLUOUS_CONST const
#endif
void bytecopy(char * SUPERFLUOUS_CONST dest,
const char *source, SUPERFLUOUS_CONST int count);
যদি FLEXIBLE_IMPLEMENTATION সত্য না হয়, তবে নীচের প্রথম উপায়ে ফাংশনটি প্রয়োগ না করার জন্য এপিআই "প্রতিশ্রুতিবদ্ধ" is
void bytecopy(char * SUPERFLUOUS_CONST dest,
const char *source, SUPERFLUOUS_CONST int count)
{
// Will break if !FLEXIBLE_IMPLEMENTATION
while(count--)
{
*dest++=*source++;
}
}
void bytecopy(char * SUPERFLUOUS_CONST dest,
const char *source, SUPERFLUOUS_CONST int count)
{
for(int i=0;i<count;i++)
{
dest[i]=source[i];
}
}
এটি করার একটি খুব নির্বোধ প্রতিশ্রুতি। আপনার এমন একজনকে কেন এমন প্রতিশ্রুতি দেওয়া উচিত যা আপনার কলারে কোনও লাভ দেয় না এবং কেবল আপনার বাস্তবায়ন সীমাবদ্ধ করে?
এগুলি উভয়ই একই ফাংশনের কার্যকর বৈধ বাস্তবায়ন যদিও আপনি যা করেছেন তা সবই আপনার পিঠের পিছনে একটি হাত বেঁধে দেওয়া হয়েছে।
তদ্ব্যতীত, এটি খুব অগভীর প্রতিশ্রুতি যা সহজেই (এবং আইনত উদ্বেগিত হয়)।
inline void bytecopyWrapped(char * dest,
const char *source, int count)
{
while(count--)
{
*dest++=*source++;
}
}
void bytecopy(char * SUPERFLUOUS_CONST dest,
const char *source,SUPERFLUOUS_CONST int count)
{
bytecopyWrapped(dest, source, count);
}
দেখুন, আমি এটি কোনওভাবেই এটি বাস্তবায়ন করেছি যদিও আমি প্রতিশ্রুতি না দিয়েছিলাম - কেবল একটি মোড়কের কাজটি ব্যবহার করে। এটি এমন হয় যখন খারাপ লোক কোনও সিনেমায় কাউকে হত্যা না করার প্রতিশ্রুতি দেয় এবং পরিবর্তে তার পাখিটিকে হত্যা করার আদেশ দেয়।
এই অতিমাত্রায় কনস্টের মুভি বাজে লোকের প্রতিশ্রুতি ছাড়া আর মূল্য নেই।
তবে মিথ্যা বলার ক্ষমতা আরও খারাপ হয়:
আমি আলোকিত হয়েছি যে আপনি জালিয়াতি কনস্ট ব্যবহার করে শিরোনাম (ঘোষণাপত্র) এবং কোড (সংজ্ঞা) এ কনস্টেট মিল করতে পারেন। কনস্ট-হ্যাপি অ্যাডভোকেটরা দাবী করেন যে এটি একটি ভাল জিনিস কারণ এটি আপনাকে কেবল সংজ্ঞাটিতে রাখতে দেয়।
// Example of const only in definition, not declaration
class foo { void test(int *pi); };
void foo::test(int * const pi) { }
তবে, কথোপকথনটি সত্য ... আপনি কেবলমাত্র ঘোষণায় একটি স্পুরিয়াস কনস্ট রাখতে পারেন এবং সংজ্ঞাতে এটিকে উপেক্ষা করতে পারেন। এটি কেবলমাত্র একটি এপিআইতে অতিমাত্রায় কনস্টকে আরও ভয়ঙ্কর জিনিস এবং একটি ভয়াবহ মিথ্যা করে তোলে - উদাহরণটি দেখুন:
class foo
{
void test(int * const pi);
};
void foo::test(int *pi) // Look, the const in the definition is so superfluous I can ignore it here
{
pi++; // I promised in my definition I wouldn't modify this
}
সমস্ত অপ্রয়োজনীয় কনস্ট আসলে বাস্তবে পরিবর্তনকারীকে পরিবর্তন করতে বা নন-কনস্ট্যান্ট রেফারেন্সের মাধ্যমে ভেরিয়েবলটি পাস করতে চাইলে তাকে অন্য স্থানীয় অনুলিপি বা একটি র্যাপার ফাংশন ব্যবহার করতে বাধ্য করে প্রয়োগকারীর কোডটি কম পঠনযোগ্য করে তোলে।
এই উদাহরণটি দেখুন। কোনটি বেশি পঠনযোগ্য? এটি কি স্পষ্ট যে দ্বিতীয় ফাংশনে অতিরিক্ত পরিবর্তনশীল হওয়ার একমাত্র কারণ হ'ল কিছু এপিআই ডিজাইনার একটি অতিমাত্রায় কনস্টে ফেলেছিলেন?
struct llist
{
llist * next;
};
void walkllist(llist *plist)
{
llist *pnext;
while(plist)
{
pnext=plist->next;
walk(plist);
plist=pnext; // This line wouldn't compile if plist was const
}
}
void walkllist(llist * SUPERFLUOUS_CONST plist)
{
llist * pnotconst=plist;
llist *pnext;
while(pnotconst)
{
pnext=pnotconst->next;
walk(pnotconst);
pnotconst=pnext;
}
}
আশা করি আমরা এখানে কিছু শিখেছি। অতিমাত্রায় কনস্ট হ'ল একটি এপিআই-ক্লটারিং চক্ষু, একটি বিরক্তিকর নাগ, একটি অগভীর এবং অর্থহীন প্রতিশ্রুতি, একটি অপ্রয়োজনীয় বাধা এবং মাঝে মধ্যে খুব বিপজ্জনক ভুলের দিকে পরিচালিত করে।