সি ও সি ++ (আপডেট উত্তর)
একটি মন্তব্যে পর্যবেক্ষণ হিসাবে, আমার আসল সমাধানটিতে দুটি সমস্যা ছিল:
- Cচ্ছিক পরামিতিগুলি কেবলমাত্র ভাষা পরিবারের সি 99 এবং পরবর্তী মানকগুলিতে উপলভ্য।
- এনাম সংজ্ঞাতে ট্রেলিং কমাটি C99 এবং তার পরেও নির্দিষ্ট।
যেহেতু আমি চাইছিলাম যে আমার কোডটি পুরানো প্ল্যাটফর্মগুলিতে কাজ করার জন্য যথাসম্ভব জেনেরিক হোক, তাই আমি এটিতে আরও একটি ছুরিকাঘাত নেওয়ার সিদ্ধান্ত নিয়েছি। এটি আগের চেয়ে লম্বা, তবে এটি সি 98 / সি 90 সামঞ্জস্যতা মোডে সেট করা সংকলক এবং প্রিপ্রসেসারগুলিতে কাজ করে। সমস্ত ম্যাক্রোগুলি উত্স কোডে উপযুক্ত সংখ্যক আর্গুমেন্ট পাস হয়, যদিও কখনও কখনও those ম্যাক্রোগুলি কিছুইতে "প্রসারিত" হয় না।
ভিজ্যুয়াল সি ++ 2013 (অরফ সংস্করণ 12) অনুপস্থিত পরামিতি সম্পর্কে সতর্কতা প্রকাশ করে, তবে এমসিপিপি (কোনও ওপেন সোর্স প্রিপ্রোসেসর যা মানের সাথে উচ্চ সম্মতি দাবি করে) বা জিসিসি 4.8.1 (-std = iso9899: 1990 -ডেপ্যান্টিক-ত্রুটিগুলি স্যুইচ) নির্গত করে কার্যকরভাবে খালি যুক্তি তালিকা সহ সেই ম্যাক্রো অনুরোধগুলির জন্য সতর্কতা বা ত্রুটি।
প্রাসঙ্গিক মান (এএনএসআই / আইএসও 9899-1990, 6.8.3, ম্যাক্রো রিপ্লেসমেন্ট) পর্যালোচনা করার পরে, আমি মনে করি যে যথেষ্ট অস্পষ্টতা রয়েছে যে এটি মানহীন হিসাবে বিবেচিত হবে না। "ফাংশনের মতো ম্যাক্রোর অনুরোধে যুক্তিগুলির সংখ্যা ম্যাক্রো সংজ্ঞাতে পরামিতিগুলির সংখ্যার সাথে একমত হবে ..."। ম্যাক্রোকে ডাকার জন্য প্রয়োজনীয় প্যারেনেসিসগুলি (এবং একাধিক পরামিতিগুলির ক্ষেত্রে কমাগুলি) যতক্ষণ না খালি যুক্তি তালিকাটি আবদ্ধ করে বলে মনে হয় না
পেছনের কমা সমস্যা হিসাবে, এটি গণনাতে একটি অতিরিক্ত শনাক্তকারী যুক্ত করে সমাধান করা হয়েছে (আমার ক্ষেত্রে, এমএমএমএম যা সনাক্তকারীকে 3999 অনুসরণ করতে পারে তার পক্ষে যতটা যুক্তিসঙ্গত বলে মনে হয় এমনকি এটি রোমান সংখ্যার সিকোয়েন্সিংয়ের স্বীকৃত নিয়ম না মানলেও ঠিক)।
একটি সামান্য ক্লিনার সমাধান এনামগুলিকে সরানো এবং ম্যাক্রোগুলিকে একটি পৃথক শিরোনামের ফাইলটিতে সমর্থন করা যেমন অন্য কোথাও একটি মন্তব্যে উল্লিখিত ছিল এবং ম্যাক্রোর নামগুলি ব্যবহার করার পরপরই ব্যবহার করা জড়িত যাতে নাম স্থান দূষিত করতে না পারে। নিঃসন্দেহে ভাল ম্যাক্রোর নামগুলিও বেছে নেওয়া উচিত, তবে এটি হাতের কাজটির জন্য পর্যাপ্ত।
আমার আপডেট হওয়া সমাধান, তারপরে আমার আসল সমাধানটি:
#define _0(i,v,x)
#define _1(i,v,x) i
#define _2(i,v,x) i##i
#define _3(i,v,x) i##i##i
#define _4(i,v,x) i##v
#define _5(i,v,x) v
#define _6(i,v,x) v##i
#define _7(i,v,x) v##i##i
#define _8(i,v,x) v##i##i##i
#define _9(i,v,x) i##x
#define k(p,s) p##s,
#define j(p,s) k(p,s)
#define i(p) j(p,_0(I,V,X)) j(p,_1(I,V,X)) j(p,_2(I,V,X)) j(p,_3(I,V,X)) j(p,_4(I,V,X)) j(p,_5(I,V,X)) j(p,_6(I,V,X)) j(p,_7(I,V,X)) j(p,_8(I,V,X)) j(p,_9(I,V,X))
#define h(p,s) i(p##s)
#define g(p,s) h(p,s)
#define f(p) g(p,_0(X,L,C)) g(p,_1(X,L,C)) g(p,_2(X,L,C)) g(p,_3(X,L,C)) g(p,_4(X,L,C)) g(p,_5(X,L,C)) g(p,_6(X,L,C)) g(p,_7(X,L,C)) g(p,_8(X,L,C)) g(p,_9(X,L,C))
#define e(p,s) f(p##s)
#define d(p,s) e(p,s)
#define c(p) d(p,_0(C,D,M)) d(p,_1(C,D,M)) d(p,_2(C,D,M)) d(p,_3(C,D,M)) d(p,_4(C,D,M)) d(p,_5(C,D,M)) d(p,_6(C,D,M)) d(p,_7(C,D,M)) d(p,_8(C,D,M)) d(p,_9(C,D,M))
#define b(p) c(p)
#define a() b(_0(M,N,O)) b(_1(M,N,O)) b(_2(M,N,O)) b(_3(M,N,O))
enum { _ a() MMMM };
#include <stdio.h>
int main(int argc, char** argv)
{
printf("%d", MMMCMXCIX * MMMCMXCIX);
return 0;
}
আসল উত্তর (যা প্রথম ছয়টি উপগ্রহ পেয়েছে, সুতরাং কেউ যদি আর এটিকে পুনরুদ্ধার না করে, তবে আপনি ভাববেন না যে আমার হালনাগাদ সমাধানটি আপভোটগুলি পেয়েছে):
পূর্বের উত্তর হিসাবে একই আত্মায়, তবে এমনভাবে সম্পন্ন হয়েছে যা কেবলমাত্র সংজ্ঞায়িত আচরণ ব্যবহার করে পোর্টেবল হওয়া উচিত (যদিও বিভিন্ন পরিবেশ সর্বদা প্রিপ্রোসেসরের কিছু দিকগুলির সাথে একমত হয় না)। কিছু প্যারামিটারগুলি alচ্ছিক হিসাবে বিবেচনা করে, অন্যকে উপেক্ষা করে, এটি __VA_ARGS__
সি ++ সহ ম্যাক্রো সমর্থন করে না এমন প্রিপ্রসেসরগুলিতে কাজ করা উচিত , টোকেন আটকানোর আগে প্যারামিটারগুলি প্রসারিত করা হয় তা নিশ্চিত করার জন্য এটি পরোক্ষ ম্যাক্রো ব্যবহার করে, এবং শেষ পর্যন্ত এটি ছোট হয় এবং আমি পড়তে সহজ মনে করি ( যদিও এটি এখনও জটিল এবং সম্ভবত পড়া সহজ নয় , কেবল সহজ):
#define g(_,__) _, _##I, _##II, _##III, _##IV, _##V, _##VI, _##VII, _##VIII, _##IX,
#define f(_,__) g(_,)
#define e(_,__) f(_,) f(_##X,) f(_##XX,) f(_##XXX,) f(_##XL,) f(_##L,) f(_##LX,) f(_##LXX,) f(_##LXXX,) f(_##XC,)
#define d(_,__) e(_,)
#define c(_,__) d(_,) d(_##C,) d(_##CC,) d(_##CCC,) d(_##CD,) d(_##D,) d(_##DC,) d(_##DCC,) d(_##DCCC,) d(_##CM,)
#define b(_,__) c(_,)
#define a b(,) b(M,) b(MM,) b(MMM,)
enum { _ a };