সি-এ #define ম্যাক্রো ব্যবহার করে printf ফাংশনের আউটপুট রান-টাইমে পরিবর্তন করা সম্ভব, যদিও এটি খুব কুৎসিত (hacky) এবং প্রোডাকশন কোডে ব্যবহার করা উচিত নয়। এটি প্রিপ্রসেসর-লেভেল টেক্সট সাবস্টিটিউশন।
কীভাবে কাজ করে
#define printf(x, y) printf(x, 50)লিখলে, এর পর থেকে সকলprintfকল দ্বিতীয় আর্গুমেন্ট হিসেবে50পাবে- ম্যাক্রো স্কোপ: যেখানে ডিক্লেয়ার করা হয়েছে সেখান থেকে ফাইল শেষ পর্যন্ত (অথবা
#undefপর্যন্ত) - ফাংশনের ভেতরে ম্যাক্রো ডিক্লেয়ার করলে সেটি ফাংশন কল হওয়ার পর থেকে প্রয়োগী হয়
উদাহরণ
#include <stdio.h>
void changePrintf() {
// এই লাইন থেকে নিচে printf("%d", x) হবে printf("%d", 50)
#define printf(x, y) printf(x, 50)
}
int main() {
int x = 40;
changePrintf(); // ম্যাক্রো এক্টিভেট
printf("%d\n", x); // 50 প্রিন্ট হবে
x = 60;
printf("%d", x); // 50 প্রিন্ট হবে
return 0;
}
আউটপুট
50
50
ব্যাখ্যা
changePrintf()কল হওয়ার পর ম্যাক্রো এক্টিভ হয়- প্রথম
printf("%d\n", x)→ প্রিপ্রসেসর এটিকেprintf("%d\n", 50)এ রূপান্তরিত করে - দ্বিতীয়
printf("%d", x)→printf("%d", 50)হয় - মূল
xএর মান (৪০, ৬০) ইগনোর হয়ে যায়
কেন এটি খারাপ অভ্যাস? ⚠️
- রিডেবিলিটি নষ্ট হয় — কোড পড়লে বোঝা যায় না কী হবে
- ডিবাগিং অসম্ভব — ডিবাগারে ম্যাক্রো এক্সপ্যানশন দেখা কঠিন
- সাইড-ইফেক্ট — আর্গুমেন্ট এক্সপ্রেশন (যেমন
printf("%d", func())) এক্সিকিউট হয়ে যেতে পারে বা না হয়ে পারে - স্পেস/প্যারেনথেসিস সেনসিটিভ —
printf (x, y)(স্পেস) কাজ নাও করতে পারে - স্ট্যান্ডার্ড লাইব্রেরি ফাংশন ওভাররাইড করাUndefined Behavior (C স্ট্যান্ডার্ড অনুযায়ী)
সঠিক বিকল্প
- ফাংশন র্যাপার:
void my_printf(const char *fmt, ...) - লগিং লাইব্রেরি (spdlog, glog, zlog)
- ফাংশন পয়েন্টার দিয়ে রান-টাইমে আউটপুট ফাংশন পরিবর্তন