ম্যাক্রোগুলি অন্য যে কোনও সরঞ্জামের মতো - হত্যায় ব্যবহৃত একটি হাতুড়িটি মন্দ নয় কারণ এটি একটি হাতুড়ি। ব্যক্তি যেভাবে এটি ব্যবহার করে এটি মন্দ। আপনি যদি নখে হাতুড়ি রাখতে চান তবে একটি হাতুড়ি একটি নিখুঁত সরঞ্জাম।
ম্যাক্রোগুলির কয়েকটি দিক রয়েছে যা সেগুলি "খারাপ" করে তোলে (আমি পরের দিকে প্রসারিত করব এবং বিকল্পগুলির পরামর্শ দেব):
- আপনি ম্যাক্রো ডিবাগ করতে পারবেন না।
- ম্যাক্রো প্রসারণ অদ্ভুত পার্শ্ব প্রতিক্রিয়া হতে পারে।
- ম্যাক্রোগুলির কোনও "নেমস্পেস" নেই, সুতরাং আপনার যদি এমন ম্যাক্রো থাকে যা অন্য কোথাও ব্যবহৃত নামের সাথে সংঘর্ষ হয় তবে আপনি ম্যাক্রো প্রতিস্থাপন পাবেন যেখানে আপনি এটি চান নি এবং এটি সাধারণত অদ্ভুত ত্রুটি বার্তাগুলির দিকে পরিচালিত করে।
- ম্যাক্রোসগুলি এমন জিনিসগুলিকে প্রভাবিত করতে পারে যা আপনি বুঝতে পারেন না।
সুতরাং আসুন এখানে কিছুটা প্রসারিত করুন:
1) ম্যাক্রোগুলি ডিবাগ করা যায় না।
যখন আপনার কাছে কোনও ম্যাক্রো রয়েছে যা কোনও সংখ্যা বা একটি স্ট্রিংয়ে অনুবাদ করে, উত্স কোডটিতে ম্যাক্রোর নাম এবং অনেক ডিবাগার থাকবে, আপনি ম্যাক্রোর সাথে অনুবাদ করে "দেখতে" পারবেন না। সুতরাং আপনি আসলে জানেন না যে কি চলছে।
প্রতিস্থাপন : ব্যবহার enum
বাconst T
"ফাংশন-সদৃশ" ম্যাক্রোগুলির জন্য, কারণ ডিবাগারটি "যেখানে আপনি যেখানে থাকেন" সোর্স লাইনের উপর "কাজ করে, আপনার ম্যাক্রো একক বিবৃতি হিসাবে কাজ করবে, এটি কোনও বিবৃতি বা একশ হোক না কেন। কী চলছে তা নির্ধারণ করা শক্ত করে তোলে।
প্রতিস্থাপন : ফাংশনগুলি ব্যবহার করুন - "দ্রুত" হওয়া দরকার হলে ইনলাইন করুন (তবে সাবধান থাকবেন যে খুব বেশি ইনলাইন কোনও ভাল জিনিস নয়)
2) ম্যাক্রো বিস্তৃতি অদ্ভুত পার্শ্ব প্রতিক্রিয়া হতে পারে।
বিখ্যাত এক #define SQUARE(x) ((x) * (x))
এবং ব্যবহার x2 = SQUARE(x++)
। এটি বাড়ে x2 = (x++) * (x++);
, যা, যদিও এটি বৈধ কোড ছিল [1], প্রায় অবশ্যই প্রোগ্রামার যা চেয়েছিল তা নয়। যদি এটি কোনও ফাংশন হয় তবে এক্স ++ করা ভাল হবে এবং এক্স কেবল একবার বৃদ্ধি করবে।
আর একটি উদাহরণ ম্যাক্রোগুলিতে "যদি অন্যথায়" হয় তবে বলুন আমাদের এটি আছে:
#define safe_divide(res, x, y) if (y != 0) res = x/y;
এবং তারপর
if (something) safe_divide(b, a, x);
else printf("Something is not set...");
এটি আসলে সম্পূর্ণ ভুল জিনিস হয়ে যায় ...
প্রতিস্থাপন : বাস্তব ফাংশন।
3) ম্যাক্রোর কোনও নামস্থান নেই
আমাদের যদি ম্যাক্রো থাকে:
#define begin() x = 0
এবং আমাদের সি ++ তে কিছু কোড রয়েছে যা ব্যবহার শুরু করে:
std::vector<int> v;
... stuff is loaded into v ...
for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it)
std::cout << ' ' << *it;
এখন, আপনি কী ত্রুটি বার্তাটি পেয়েছেন বলে মনে করেন এবং আপনি কোনও ত্রুটিটি কোথায় খুঁজছেন [ধরে নিচ্ছেন আপনি সম্পূর্ণরূপে ভুলে গেছেন - বা এমনকি জানেন না - এমন কোনও শিরোনাম ফাইল যা অন্য কেউ লিখেছেন তাতে ম্যাক্রোটি বেঁচে থাকে? [এবং আরও মজাদার যদি আপনি অন্তর্ভুক্ত করার আগে সেই ম্যাক্রো অন্তর্ভুক্ত করেন - আপনি কোডটি নিজের দিকে তাকানোর সময় আপনি অদ্ভুত ত্রুটিতে নিমজ্জিত হবেন যা কোনও অর্থহীন নয়।
প্রতিস্থাপন : ঠিক আছে, "বিধি" হিসাবে প্রতিস্থাপনের মতো এতটা নেই - কেবল ম্যাক্রোগুলির জন্য বড় হাতের নাম ব্যবহার করুন এবং অন্যান্য জিনিসের জন্য সমস্ত বড় হাতের নাম কখনও ব্যবহার করবেন না।
4) ম্যাক্রোসের এমন প্রভাব রয়েছে যা আপনি বুঝতে পারবেন না
এই ফাংশনটি নিন:
#define begin() x = 0
#define end() x = 17
... a few thousand lines of stuff here ...
void dostuff()
{
int x = 7;
begin();
... more code using x ...
printf("x=%d\n", x);
end();
}
এখন, ম্যাক্রোর দিকে না তাকিয়ে আপনি ভাববেন যে সূচনাটি একটি ফাংশন, এটি এক্সকে প্রভাবিত করবে না।
এই ধরণের জিনিস, এবং আমি আরও জটিল উদাহরণগুলি দেখেছি, সত্যিই আপনার দিনকে জগাখিচুড়ি করতে পারে!
প্রতিস্থাপন : হয় এক্স সেট করতে ম্যাক্রো ব্যবহার করবেন না, বা একটি আর্গুমেন্ট হিসাবে এক্স পাস করুন।
এমন সময় আছে যখন ম্যাক্রোগুলি ব্যবহার করা অবশ্যই উপকারী। একটি উদাহরণ ফাইল / লাইন তথ্য পাস করার জন্য ম্যাক্রোগুলির সাথে একটি ফাংশন মোড়ানো:
#define malloc(x) my_debug_malloc(x, __FILE__, __LINE__)
#define free(x) my_debug_free(x, __FILE__, __LINE__)
এখন আমরা my_debug_malloc
কোডটিতে নিয়মিত ম্যালোক হিসাবে ব্যবহার করতে পারি , তবে এটিতে অতিরিক্ত যুক্তি রয়েছে, সুতরাং যখন এটি শেষ হয় এবং আমরা "কোন স্মৃতি উপাদানগুলি মুক্তি পায় নি" স্ক্যান করি, তখন আমরা মুদ্রণ করতে পারি যেখানে বরাদ্দটি এতদূর হয়েছে প্রোগ্রামার লিকটি সনাক্ত করতে পারে।
[1] "এক সিকোয়েন্স পয়েন্টে" একবারে একাধিক পরিবর্তনশীল আপডেট করা এটি অপরিজ্ঞাত আচরণ। একটি ক্রম বিন্দু বিবৃতি হিসাবে ঠিক একই নয়, তবে বেশিরভাগ উদ্দেশ্য এবং উদ্দেশ্যগুলির জন্য আমাদের এটিকে বিবেচনা করা উচিত। এটি করার x++ * x++
ফলে x
দু'বার আপডেট হবে যা অপরিজ্ঞাত এবং সম্ভবত বিভিন্ন সিস্টেমে বিভিন্ন মান এবং বিভিন্ন ফলাফলের মান হতে x
পারে।
#pragma
ম্যাক্রো নয়।