শর্তসাপেক্ষ সংকলনের জন্য শর্টকাট হিসাবে সি / সি ++ ম্যাক্রোগুলি ব্যবহার করা কি একটি ভাল অনুশীলন?


13

ধরা যাক আমি আমার কোডে বিভিন্ন ধরণের আউটপুট বার্তা রাখতে চাই। এর মধ্যে একটি DEBUGহ'ল কোডটি যখন ডিবাগ মোডে সংকলিত হয় কেবল তখনই এটি মুদ্রিত হয়।

সাধারণত আমি কিছু লিখতে হবে

#ifdef DEBUG
    std::cout << "Debug message" << std::endl;
#endif

যা অনেক জায়গায় ব্যবহার করা বেশ জটিল এবং বিরক্তিকর।

কোড স্নিপেটের জন্য কোনও ম্যাক্রো সংজ্ঞায়িত করা কি একটি ভাল অনুশীলন, তাই আপনি কি এটি এইভাবে ব্যবহার করতে চান?

MSG_DEBUG("Debug message")

বা ম্যাক্রো ছাড়াই কীভাবে এটি মোকাবেলা করার জন্য আরও কোনও মার্জিত উপায় আছে? আমি সি এবং সি ++ উভয় ক্ষেত্রেই সম্ভাব্য সমাধানগুলি সম্পর্কে আগ্রহী, কারণ আমি বিভিন্ন প্রকল্পে উভয় ভাষা ব্যবহার করছি।



আপনি কেন কোনও ফাংশনে শর্তাধীন কোড রাখেন না এবং এটিকে কেন কল করবেন না তা প্রশ্ন থেকে পরিষ্কার নয়। আরও কিছু বাধা আছে যা প্রতিরোধ করতে পারে?
অ্যালেক্স

@ গ্যাनेट আপনি যে প্রশ্নটি উল্লেখ করেছেন তা এতই বিস্তৃত যে বেশিরভাগ লোক এটিকে এই বিষয়ের সাথে সংযুক্ত করবেন না, বিশেষত যখন তারা ইন্টারনেটে এই নির্দিষ্ট প্রশ্নটি খুঁজছেন।
Eenoku

3
আপনার প্রশ্নটি সি এবং সি ++ উভয়ের সাথে ট্যাগ করা আছে , তবে সেগুলি বেশ আলাদা ভাষা। আপনি কোনটির কথা বলছেন তা স্পষ্ট করে বলতে পারেন? আপনার উদাহরণটি সিতে পুরোপুরি সূক্ষ্ম হবে তবে constexpr ifউদাহরণস্বরূপ সি ++ এর সাথে আরও ভালভাবে প্রয়োগ করা যেতে পারে ।
Jörg W Mittag

1
অন্যদিকে, ডায়াগনস্টিক্সে যাওয়া উচিত STDERR। এছাড়াও, পরিবর্তে এটির NDEBUGমতো নির্ভর করে না কেন assert()? তারপরে আপনি এটির মতো সংজ্ঞা দিতে পারেন #define DEBUG_MSG(MSG) assert(std::cerr << MSG)যা স্ট্রিম-স্টেটও পরীক্ষা করে।
হস্তান্তরকারী

উত্তর:


19

অবশ্যই, আপনি যদি প্রথম স্থানে ম্যাক্রোগুলি ব্যবহার করে ঠিক থাকেন তবে একই শর্তসাপেক্ষ কোডটি পুনরাবৃত্তি না করে প্যারামাইট্রাইজড সংজ্ঞা দেওয়া ভাল কোডিংয়ের কোনও মাপের দ্বারা অবশ্যই পছন্দনীয়।

আপনার কি আদৌ ম্যাক্রো ব্যবহার করা উচিত? আমার দৃষ্টিতে আপনার উচিত হওয়া উচিত, যেহেতু এটি সি তে গৃহীত অনুশীলন, এবং যে কোনও ম্যাক্রো-কম সমাধানের জন্য কমপক্ষে কিছু ডিবাগ মোডের বাইরেও কার্যকর করা দরকার। টিপিকাল সি প্রোগ্রামারটি যে কোনও সময় অপ্রয়োজনীয় রান-টাইম প্রচেষ্টার চেয়ে কিছুটা কুৎসিত ম্যাক্রোটি বেছে নেবে।


13

এখানে ব্যক্তিগত পছন্দের একটি উপাদান রয়েছে তবে সি ++ এ আমি হেডার ফাইলটিতে এটি করতে পছন্দ করি:

#ifdef _DEBUG
    void DebugMessage(...);
#else
    inline void DebugMessage(...) {}
#endif

যাতে ফাংশনটি রিলিজ বিল্ডগুলিতে অন্তর্ভুক্ত থাকে তবে এটি ডিবাগ বিল্ডে একটি যথাযথ ফাংশন যাতে আপনার যথাযথ টাইপ চেকিং, বুদ্ধিমান ত্রুটি বার্তা ইত্যাদি পাওয়া যায় এবং পরে আরও কার্যকারিতা যুক্ত করার ক্ষমতা (সম্ভবত লগিং?) থাকতে পারে।

স্পষ্টতই, আপনাকেও .cppএকটি #ifdef _DEBUGব্লকের ফাইলটিতে ফাংশনের সংশ্লিষ্ট সংজ্ঞাটি এনকাস করতে হবে ।


কল কল ওভারহেড এখনও এখানে উপস্থিত, তাই না?
Eenoku

7
যদি আপনার সংকলক একটি রিলিজ বিল্ডে পরিচিত খালি ফাংশনটি কল করার জন্য কোড তৈরি করে, দক্ষতা বৃদ্ধির জন্য আপনার প্রথম এবং সবচেয়ে বড় কাজটি করতে হবে আরও অনেক ভাল সংকলক। এটি সত্যিই তুচ্ছ অপ্টিমাইজেশন।
ডেভিড থর্নলি

@ Okনোকু না, যেমন ডেভিড বলেছেন, এটি আপনার ব্যবহার করা কোনও সংকলক দ্বারা মুছে ফেলা হবে।
জ্যাক এইডলি 17'18

3
এখানে একটি মূল পার্থক্য রয়েছে: ম্যাক্রো (এটি কীভাবে লেখা হয়েছে তার উপর নির্ভর করে) তার যুক্তি প্রকাশের মূল্যায়ন করবে না, যখন ফাংশনটি সর্বদা এটি করবে। এছাড়াও, ভারার্গস ফাংশনে অ-তুচ্ছ আর্গুমেন্টগুলি পাস করার জন্য এটি অপরিজ্ঞাত আচরণ (এবং সাধারণত সংকলক সতর্কতাগুলি ট্রিগার করে)।
সেবাস্তিয়ান রেডল


2

অবশ্যই, নিশ্চিত হয়ে নিন যে আপনি আপনার দল দ্বারা প্রদত্ত কোডের নির্দেশিকাতে পদক্ষেপ নিচ্ছেন না। শর্তে যদি সিস্টেমের অন্য কোনও কোড সাধারণের মাধ্যমে একই কার্যকারিতাটি পৌঁছানোর চেষ্টা না করে তা নিশ্চিত করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.