#ifdef বনাম #if - কোডের নির্দিষ্ট বিভাগগুলির সংকলন সক্ষম / অক্ষম করার জন্য কোন পদ্ধতি হিসাবে ভাল / নিরাপদ?


112

এটি স্টাইলের বিষয় হতে পারে তবে আমাদের দেব দলে কিছুটা বিভাজন রয়েছে এবং আমি ভাবছিলাম যে অন্য কারও বিষয়ে এই বিষয়ে কিছু ধারণা থাকলে ...

মূলত, আমাদের কিছু ডিবাগ প্রিন্ট স্টেটমেন্ট রয়েছে যা আমরা সাধারণ বিকাশের সময় বন্ধ করে দিই। ব্যক্তিগতভাবে আমি নিম্নলিখিতগুলি করতে পছন্দ করি:

//---- SomeSourceFile.cpp ----

#define DEBUG_ENABLED (0)

...

SomeFunction()
{
    int someVariable = 5;

#if(DEBUG_ENABLED)
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

দলের কেউ কেউ যদিও নিম্নলিখিতটি পছন্দ করেন:

// #define DEBUG_ENABLED

...

SomeFunction()
{
    int someVariable = 5;

#ifdef DEBUG_ENABLED
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

... এই পদ্ধতিগুলির মধ্যে কোনটি আপনার কাছে ভাল লাগে এবং কেন? আমার অনুভূতিটি হ'ল প্রথমটি নিরাপদ কারণ এখানে সবসময় সংজ্ঞায়িত কিছু থাকে এবং অন্য সংজ্ঞাগুলি অন্য কোথাও ধ্বংস করতে পারে এমন কোনও আশঙ্কা নেই।


দ্রষ্টব্য: এর সাথে #ifআপনি #elifএরপরেও সামঞ্জস্যপূর্ণ পদ্ধতিতে ব্যবহার করতে পারেন #ifdef। সুতরাং, পরিবর্তে শুধু ব্যবহারের #define BLAH, ব্যবহার #define BLAH 1সঙ্গে #if BLAH, ইত্যাদি ...
অ্যান্ড্রু

উত্তর:


82

আমার প্রাথমিক প্রতিক্রিয়া #ifdefঅবশ্যই ছিল , তবে আমি মনে করি #ifএটির জন্য আসলে কিছু উল্লেখযোগ্য সুবিধা রয়েছে - এখানে কেন:

প্রথমত, আপনি DEBUG_ENABLEDপ্রিপ্রসেসর এবং সংকলিত পরীক্ষায় ব্যবহার করতে পারেন । উদাহরণ - প্রায়শই, আমি যখন ডিবাগ সক্ষম হয় তখন দীর্ঘ সময়সীমা চাই, তাই ব্যবহার করে #ifআমি এটি লিখতে পারি

  DoSomethingSlowWithTimeout(DEBUG_ENABLED? 5000 : 1000);

... পরিবর্তে ...

#ifdef DEBUG_MODE
  DoSomethingSlowWithTimeout(5000);
#else
  DoSomethingSlowWithTimeout(1000);
#endif

দ্বিতীয়ত, আপনি যদি একটি #defineথেকে বৈশ্বিক ধ্রুবক স্থানান্তর করতে চান তবে আপনি আরও ভাল অবস্থানে আছেন । #defineগুলি বেশিরভাগ সি ++ প্রোগ্রামারদের দ্বারা সজ্জিত হয়।

এবং, তৃতীয়, আপনি বলেছেন যে আপনি নিজের দলে বিভক্ত হয়েছেন। আমার অনুমান এর অর্থ এই যে বিভিন্ন সদস্য ইতিমধ্যে বিভিন্ন পন্থা অবলম্বন করেছেন এবং আপনার মানক করা দরকার। রুলিং যা #ifপছন্দসই পছন্দ এর মানে হল যে কোডটি ব্যবহার করে কোডটি #ifdefসংকলিত হবে - এবং রান- এমনকি DEBUG_ENABLEDমিথ্যা হলেও । এবং ডিবাগ আউটপুট তৈরি করা এবং এটি ত্রুটি-বিপরীত হওয়া উচিত নয় যখন উত্পাদিত হয় এটি সন্ধান করা এবং সরানো অনেক সহজ।

ওহ, এবং একটি ছোটখাটো পঠনযোগ্যতা বিন্দু। আপনার নিজের মধ্যে 0/1 এর পরিবর্তে সত্য / মিথ্যা ব্যবহার করতে সক্ষম হওয়া উচিত #defineএবং মানটি একটি একক লাক্ষিক টোকেন হওয়ায় এটি একবারে আপনার চারপাশে প্রথম বন্ধনী প্রয়োজন হয় না।

#define DEBUG_ENABLED true

পরিবর্তে

#define DEBUG_ENABLED (1)

ডিবাগিং সক্ষম / অক্ষম করার জন্য ধ্রুবকটি ব্যবহার করা হতে পারে না, সুতরাং # আইফডিফকে # ডিফাইন দিয়ে 0 এ ট্রিগার করা এত সৌম্য হতে পারে না। সত্য / মিথ্যা হিসাবে, সেগুলি C99 এ যুক্ত হয়েছিল এবং C89 / C90 তে নেই।
মাইকেল কারম্যান

মিশেল: তিনি / তিনি # আইফডিএফ ব্যবহারের বিরুদ্ধে কথা বলছিলেন ?!
জন কেজ

7
হ্যাঁ, একটি সমস্যা #ifdefহ'ল এটি এমন জিনিসগুলির সাথে কাজ করে যা সংজ্ঞায়িত হয় না; সেগুলি ইচ্ছাকৃতভাবে সংজ্ঞায়িত করা হয়নি বা টাইপের কারণে বা আপনার কাছে কী আছে তা নির্ধারণ করা হচ্ছে।
bames53

6
উত্তরের সাথে আপনার যোগটি ভুল wrong #if DEBUG_ENBALEDপ্রিপ্রোসেসর দ্বারা চিহ্নিত ত্রুটি নয়। যদি DEBUG_ENBALEDসংজ্ঞায়িত করা হয় না, এটা টোকেন বিস্তৃতি 0মধ্যে #ifনির্দেশনা।
আর .. গীটহাব বন্ধ করুন ICE

6
@ আর .. অনেকগুলি সংকলকগুলিতে আপনি "#if DEBUG_ENABLED" এর জন্য একটি সতর্কতা সক্ষম করতে পারবেন যখন DEBUG_ENABLED সংজ্ঞায়িত হয় না। জিসিসিতে "-উন্ডাফ" ব্যবহার করুন। মাইক্রোসফ্ট ভিজ্যুয়াল স্টুডিওতে লেভেল 1 সতর্কতা হিসাবে C4668 চালু করতে "/ w14668" ব্যবহার করুন।
উইল

56

তারা দুজনেই ঘৃণ্য। পরিবর্তে, এটি করুন:

#ifdef DEBUG
#define D(x) do { x } while(0)
#else
#define D(x) do { } while(0)
#endif

তারপর যখনই আপনি ডিবাগ কোড প্রয়োজন, এটা ভিতরে রাখা D();। এবং আপনার প্রোগ্রাম এর জঘন্য mazes সঙ্গে দূষিত নয় #ifdef


6
@MatthieuM। আসলে, আমি মনে করি মূল সংস্করণটি ভাল ছিল। সেমিকোলনটি একটি খালি বিবৃতি হিসাবে ব্যাখ্যা করা হবে। তবে সেমিকোলন ভুলে যাওয়া বিপজ্জনক হতে পারে make
কেসি কুবাল

31

#ifdef শুধুমাত্র একটি টোকেন সংজ্ঞায়িত করা হয়েছে কিনা তা পরীক্ষা করে দেখুন

#define FOO 0

তারপর

#ifdef FOO // is true
#if FOO // is false, because it evaluates to "#if 0"

20

আমাদের একাধিক ফাইল জুড়ে একই সমস্যা রয়েছে এবং লোকেরা একটি "বৈশিষ্ট্যযুক্ত পতাকা" ফাইল অন্তর্ভুক্ত করতে ভুলে যাওয়ার সমস্যাটি থাকে (414 ফাইলের কোডবেস সহ এটি করা সহজ) there

যদি আপনার বৈশিষ্ট্য থাকে:

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE 1

#endif // FEATURE_H

তবে আপনি file.cpp এ হেডার ফাইলটি অন্তর্ভুক্ত করতে ভুলে গেছেন:

#if COOL_FEATURE
    // definitely awesome stuff here...
#endif

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

আমরা এই কেসটির সংশোধন করার পাশাপাশি কোনও বৈশিষ্ট্যের স্থিতির জন্য পরীক্ষা করার জন্য বহনযোগ্য উপায় গ্রহণ করেছি: ফাংশন ম্যাক্রো।

যদি আপনি উপরের বৈশিষ্ট্যটি h পরিবর্তন করে থাকেন:

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE() 1

#endif // FEATURE_H

তবে আপনি আবার file.cpp এ হেডার ফাইলটি অন্তর্ভুক্ত করতে ভুলে গেছেন:

#if COOL_FEATURE()
    // definitely awseome stuff here...
#endif

একটি পূর্বনির্ধারিত ফাংশন ম্যাক্রোর ব্যবহারের কারণে প্রিপ্রোসেসরটি ভুল হয়ে গিয়েছিল।


17

শর্তসাপেক্ষ সংকলন সম্পাদনের উদ্দেশ্যে, # আইফ এবং # আইডিডিফ প্রায় একই, তবে বেশ নয়। যদি আপনার শর্তসাপেক্ষ সংকলন দুটি চিহ্নের উপর নির্ভর করে তবে #ifdef কাজ করবে না। উদাহরণস্বরূপ, ধরুন আপনার কাছে দুটি শর্তসাপেক্ষ সংকলন চিহ্ন রয়েছে, PRO_VERSION এবং TRIAL_VERSION, আপনার কাছে এরকম কিছু থাকতে পারে:

#if defined(PRO_VERSION) && !defined(TRIAL_VERSION)
...
#else
...
#endif

উপরের #ifdef ব্যবহার করা আরও জটিল হয়ে ওঠে, বিশেষত # অন্যান্য অংশে কাজ করা।

আমি এমন কোডে কাজ করি যা শর্তসাপেক্ষ সংকলনটি ব্যাপকভাবে ব্যবহার করে এবং আমাদের #if & #ifdef এর মিশ্রণ রয়েছে। আমরা সহজ ক্ষেত্রে # ইফদেফ / # আইফেনডিফ ব্যবহার করি এবং যখনই দুই বা ততোধিক চিহ্নের মূল্যায়ন হচ্ছে।


1
মধ্যে #if definedকি definedএটি একটি মূল শব্দ বা কি?
nmxprime

15

আমি মনে করি এটি পুরোপুরি শৈলীর প্রশ্ন। উভয়ই সত্যই অন্যটির থেকে সুস্পষ্ট সুবিধা পায় না।

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


8

আমি নিজে পছন্দ করি:

#if defined(DEBUG_ENABLED)

যেহেতু বিপরীতমুখী অবস্থার সন্ধান করা কোড তৈরি করা এটি সহজ করে তোলে:

#if !defined(DEBUG_ENABLED)

বনাম

#ifndef(DEBUG_ENABLED)

8
ব্যক্তিগতভাবে আমি মনে করি যে এই ছোট্ট বিস্মৃত চিহ্নটি মিস করা আরও সহজ!
জন কেজ

6
সিনট্যাক্স হাইলাইটিং সহ? :) সিনট্যাক্স হাইলাইটে, "ifndef" এ "এন" স্পষ্ট করা খুব শক্ত কারণ এটি সমস্ত রঙ একই।
জিম বক

ঠিক আছে, আমি বোঝাতে চেয়েছি যে # আইফেন্ডিফটি #if এর চেয়ে স্পট করা সহজ! যখন আপনি #if সংজ্ঞায়নের তুলনায় তুলনা করেন .. তবে সমস্ত #if সংজ্ঞায়িত / # যদি দেওয়া হয়! বনাম # ifdef / # ifndef, হয় সমানভাবে মিস-পঠনযোগ্য!
জন কেজ

@ জোনকেজ আমি জানি যে এই মন্তব্যের কয়েক বছর হয়ে গেছে তবে আমি আপনাকে উল্লেখ করতে চাই যে আপনি #if ! definedএটি !আরও বিশিষ্ট এবং মিস করা কঠিন হিসাবে লিখতে পারেন ।
ফারাপ

@ ফারাপ - এটি অবশ্যই উন্নতির মতো দেখাচ্ছে :)
জোন কেজ

7

এটি স্টাইলের বিষয়। তবে আমি এটি করার আরও সংক্ষিপ্ত পদ্ধতির প্রস্তাব দিচ্ছি:

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print
#endif

debug_print("i=%d\n", i);

আপনি এটি একবার করুন, তারপরে সর্বদা ছাপাতে বা কিছুই না করতে ডিবাগ_প্রিন্ট () ব্যবহার করুন। (হ্যাঁ, এটি উভয় ক্ষেত্রেই সংকলন করবে)) এইভাবে, আপনার কোডটি প্রিপ্রোসেসর নির্দেশিকাগুলি দিয়ে তৈরি হবে না।

যদি আপনি সতর্কতাটি পান "এক্সপ্রেশনটির কোনও প্রভাব নেই" এবং এ থেকে মুক্তি পেতে চান তবে এখানে একটি বিকল্প রয়েছে:

void dummy(const char*, ...)
{}

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print dummy
#endif

debug_print("i=%d\n", i);

3
সম্ভবত মুদ্রণ ম্যাক্রো সর্বোপরি সর্বোত্তম উদাহরণ ছিল না - আমরা আমাদের আরও বেশি স্ট্যান্ডার্ড ডিবাগ কোডের জন্য ইতিমধ্যে আমাদের কোডবেসে এটি করি। আপনি অতিরিক্ত ডিবাগিং চালু করতে পারেন এমন অঞ্চলের জন্য আমরা #if / #ififififised বিট ব্যবহার করি ..
জন কেজ

5

#ifকার্যকারিতা বন্ধ করতে আপনাকে 0 এ সেট করার বিকল্প দেয়, এমনকি স্যুইচটি রয়েছে তা সনাক্ত করে।
ব্যক্তিগতভাবে আমি সর্বদা #define DEBUG 1তাই আমি এটি কোনও # আইফোন বা # আইফডিএফ দিয়ে ধরতে পারি


1
এটি ব্যর্থ হয়েছে, যেহেতু # ডিফাইন DEBUG = 0 এখন #if চালাবে না তবে #ifdef
চালাবে

1
মূল কথাটি, আমি হয় পুরোপুরি DEBUG মুছে ফেলতে পারি বা এটি অক্ষম করতে কেবল 0 এ সেট করতে পারি।
মার্টিন বেকেট

এটা করা উচিত #define DEBUG 1। না#define DEBUG=1
কেশাভা জিএন

4

# আইফ এবং # ডেফাইন এমওয়াই_ম্যাক্রো (0)

# আইফ ব্যবহারের অর্থ হ'ল আপনি একটি "সংজ্ঞায়িত" ম্যাক্রো তৈরি করেছেন, অর্থাত্ "(0)" দ্বারা প্রতিস্থাপিত করার জন্য কোডে অনুসন্ধান করা হবে। এটি "ম্যাক্রো হেল" আমি সি ++ এ দেখতে ঘৃণা করি কারণ এটি সম্ভাব্য কোড সংশোধন সহ কোডটিকে দূষিত করে।

উদাহরণ স্বরূপ:

#define MY_MACRO (0)

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

g ++ এ নিম্নলিখিত ত্রুটি দেয়:

main.cpp|408|error: lvalue required as left operand of assignment|
||=== Build finished: 1 errors, 0 warnings ===|

কেবল একটি ত্রুটি।

যার অর্থ হল যে আপনার ম্যাক্রো আপনার সি ++ কোডের সাথে সফলভাবে ইন্টারঅ্যাক্ট করেছে: ফাংশনে কলটি সফল হয়েছিল। এই সাধারণ ক্ষেত্রে, এটি মজাদার। তবে আমার কোডের সাথে নিঃশব্দে ম্যাক্রো খেলে আমার নিজের অভিজ্ঞতা আনন্দ এবং ফুলফিলামিতে পূর্ণ নয়, তাই ...

# আইফডিফ এবং # ডেফাইন এমওয়াই_ম্যাক্রো

#Ifdef ব্যবহারের অর্থ আপনি কোনও কিছু "সংজ্ঞায়িত" করেন। আপনি এটি একটি মূল্য দিতে না যে। এটি এখনও দূষণকারী, তবে কমপক্ষে, এটি "কিছুই দ্বারা প্রতিস্থাপিত হবে", এবং সি ++ কোডটি লেজিটিমিট কোড বিবৃতি হিসাবে দেখা যায় না। উপরের একই কোডটি, একটি সাধারণ সংজ্ঞা সহ এটি:

#define MY_MACRO

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

নিম্নলিখিত সতর্কতা দেয়:

main.cpp||In function int main(int, char**)’:|
main.cpp|406|error: expected unqualified-id before ‘=’ token|
main.cpp|399|error: too few arguments to function int doSomething(int)’|
main.cpp|407|error: at this point in file|
||=== Build finished: 3 errors, 0 warnings ===|

তাই ...

উপসংহার

আমি বরং আমার কোডে ম্যাক্রোগুলি ছাড়া বাঁচতে পারি, তবে একাধিক কারণে (শিরোনাম রক্ষীদের সংজ্ঞা দেওয়া, বা ম্যাক্রো ডিবাগ করা), আমি পারি না।

তবে কমপক্ষে, আমি আমার বৈধ সি ++ কোড দিয়ে তাদের সর্বনিম্ন ইন্টারেক্টিভ তৈরি করতে চাই। যার অর্থ হল মান ব্যতীত # ডেফাইন ব্যবহার করা, # আইফডিএফ এবং # আইফেন্ডাফ ব্যবহার করা (বা এমনকি # জিম বাকের পরামর্শ অনুসারে সংজ্ঞায়িত) এবং সর্বোপরি তাদের নাম দেওয়া এত দীর্ঘ এবং তার সঠিক মনের কেউই ব্যবহার করবেন না এটি "সুযোগে", এবং এটি কোনওভাবেই বৈধ সি ++ কোডকে প্রভাবিত করবে না।

পোস্ট স্ক্রিপ্টাম

এখন, আমি যখন আমার পোস্টটি পুনরায় পড়ছি, আমি অবাক হয়েছি যে আমার সংজ্ঞায় যুক্ত করার জন্য এমন কোনও মান খুঁজে বের করার চেষ্টা করা উচিত যা কখনও কখনও সি ++ হতে পারে না। কিছুটা এইরকম

#define MY_MACRO @@@@@@@@@@@@@@@@@@

এটি # আইডিডিডিএফ এবং # আইডিফাইফের সাথে ব্যবহার করা যেতে পারে তবে কোনও ফাংশনের অভ্যন্তরে কোডটি সংকলন করতে দেওয়া হবে না ... আমি জি ++ এ এটি সফলভাবে চেষ্টা করেছি এবং এটি ত্রুটি দিয়েছে:

main.cpp|410|error: stray ‘@’ in program|

মজাদার. :-)


আমি সম্মত হই যে ম্যাক্রোগুলি বিপজ্জনক হতে পারে তবে এটি প্রথম উদাহরণটি ডিবাগ করার পক্ষে মোটামুটি সুস্পষ্ট হবে এবং অবশ্যই এটি কেবল একটি ত্রুটি দেয়। কেন আপনি আরও আশা করবেন? ম্যাক্রোগুলির ফলস্বরূপ আমি অনেক ন্যাশিয়র ত্রুটি দেখেছি ...
জন কেজ ২

এটি সত্য যে একটি সমাধানের মধ্যে পার্থক্যটি প্রায় তুচ্ছ। তবে এই ক্ষেত্রে, আমরা দুটি প্রতিযোগিতামূলক কোডিং শৈলীর বিষয়ে কথা বলছি, তবুও তুচ্ছটিকেও এড়ানো যায় না, কারণ এর পরে, যা কিছু বাকী রয়েছে তা ব্যক্তিগত স্বাদ (এবং সেই সময়ে, আমি বিশ্বাস করি এটি স্বাভাবিক করা উচিত নয়) )
পারাসেবল

4

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

#ifdef macro

"" যদি ম্যাক্রো সংজ্ঞায়িত করা হয় "বা" ম্যাক্রো বিদ্যমান থাকলে "এর অর্থ। ম্যাক্রোর মান এখানে কিছু যায় আসে না। এটা যাই হোক না কেন হতে পারে।

#if macro

যদি সর্বদা একটি মানের সাথে তুলনা করা হয়। উপরের উদাহরণে এটি স্ট্যান্ডার্ড অন্তর্নিহিত তুলনা:

#if macro !=0

#if ব্যবহারের জন্য উদাহরণস্বরূপ

#if CFLAG_EDITION == 0
    return EDITION_FREE;
#elif CFLAG_EDITION == 1
    return EDITION_BASIC;
#else
    return EDITION_PRO;
#endif

আপনি এখন হয় আপনার কোডটিতে হয় CFLAG_EDITION এর সংজ্ঞা রাখতে পারেন

#define CFLAG_EDITION 1 

অথবা আপনি সংকলক পতাকা হিসাবে ম্যাক্রো সেট করতে পারেন। এছাড়াও এখানে দেখুন


2

প্রথমটি আমার কাছে পরিষ্কার মনে হয় seems সংজ্ঞায়িত / সংজ্ঞায়িত তুলনায় তুলনামূলকভাবে তুলনামূলক তুলনায় এটি আরও প্রাকৃতিক বলে মনে হচ্ছে এটি একটি পতাকা হিসাবে তৈরি হয়েছে।


2

উভয়ই সমান সমান। অভিব্যক্তিমূলক ব্যবহারে, #ifdef কেবল সংজ্ঞায়িতকরণের জন্য পরীক্ষা করা হয় (এবং আমি আপনার উদাহরণে যা ব্যবহার করতাম), যেখানে #if আরও জটিল অভিব্যক্তিতে ব্যবহৃত হয়, যেমন #if সংজ্ঞায়িত (এ) && সংজ্ঞায়িত (বি)।


1
ওপি "#ifdef" এবং "#if সংজ্ঞায়িত" এর মধ্যে কোনটি "# ifdef / # সংজ্ঞায়িত করা হয়" এবং "#if" এর মধ্যে ভাল তা জিজ্ঞাসা করছিল না।
শংকিত

1

একটু ওটি, তবে প্রিপ্রোসেসরের সাথে লগিং চালু / বন্ধ করা অবশ্যই সি ++ এ সাব-অনুকূল mal অ্যাপাচি এর লগ 4cxx এর মতো দুর্দান্ত লগিং সরঞ্জাম রয়েছে যা ওপেন সোর্স এবং আপনি কীভাবে আপনার অ্যাপ্লিকেশন বিতরণ করবেন তা সীমাবদ্ধ করে না don't এগুলি আপনাকে পুনঃসংশোধন ছাড়াই লগিংয়ের স্তর পরিবর্তন করার অনুমতি দেয়, আপনি লগিং বন্ধ করে রাখলে খুব কম ওভারহেড থাকে এবং আপনাকে উত্পাদনে সম্পূর্ণ লগিং বন্ধ করার সুযোগ দেয়।


1
আমি সম্মত, এবং আমরা আসলে আমাদের কোডটিতে এটি করি, আপনি কেবল #if ইত্যাদি ব্যবহারের জন্য এমন কিছু উদাহরণ চেয়েছিলেন
জোন কেজ

1

আমি ব্যবহার করতাম #ifdef, তবে যখন আমি ডকুমেন্টেশনের জন্য ডক্সিজেনের দিকে স্যুইচ করলাম, আমি দেখতে পেলাম যে মন্তব্য করা আউট ম্যাক্রোগুলি নথিভুক্ত করা যাবে না (বা কমপক্ষে, ডক্সিজেন একটি সতর্কতা উত্পন্ন করে)। এর অর্থ আমি বর্তমানে সক্ষম নয় এমন বৈশিষ্ট্য-স্যুইচ ম্যাক্রোগুলি নথিভুক্ত করতে পারি না।

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

অতএব, এই ক্ষেত্রে, সর্বদা ম্যাক্রোগুলি সংজ্ঞায়িত করা এবং ব্যবহার করা ভাল #if


0

আমি এটি নির্ধারণ করতে সর্বদা #ifdef এবং সংকলক পতাকা ব্যবহার করেছি ...


কোনও বিশেষ কারণ (কৌতূহলের বাইরে)?
জন কেজ

2
সত্যি কথা বলতে আমি কখনই এ নিয়ে ভাবিনি - আমি যেভাবে কাজ করেছি সেখানে এটি কীভাবে হয়েছে। এটা তোলে সুবিধা হলো এর পরিবর্তে একটি প্রকাশনা বিল্ড সব আপনাকে যা করতে হবে একটি কোড পরিবর্তন তৈরীর ডিবাগ জন্য 'করতে ডিবাগ', বা 'করতে উৎপাদন' নিয়মিত হয় দিতে না
tloach

0

বিকল্পভাবে, আপনি একটি গ্লোবাল ধ্রুবক ঘোষণা করতে পারেন, এবং প্রিপ্রসেসর # আইফ এর পরিবর্তে সি ++ ব্যবহার করতে পারেন। সংকলকটি আপনার জন্য অব্যক্ত শাখাগুলি অপ্টিমাইজ করা উচিত এবং আপনার কোডটি পরিষ্কার হবে।

এখানে কি সি ++ Gotchas স্টিফেন দ্বারা সি Dewhurst যদি # ব্যবহার সম্পর্কে বলেছেন।


1
এটি একটি লম্পট সমাধান, এটিতে নিম্নলিখিত সমস্যা রয়েছে: ১. কেবলমাত্র ফাংশনগুলিতে কাজ করে, আপনি অপ্রয়োজনীয় শ্রেণীর চলক ইত্যাদি অপসারণ করতে পারবেন না Comp. কম্পাইলারগুলি অ্যাক্সেসযোগ্য কোড সম্পর্কে সতর্কতা ফেলে দিতে পারে 3.. যদি কোডটি এখনও সঙ্কলনের প্রয়োজন হয়, যার অর্থ আপনাকে আপনার সমস্ত ডিবাগ ফাংশনগুলি সংজ্ঞায়িত করতে হবে, ইত্যাদি।
ডন নিউফিল্ড

প্রথম প্রশ্নটি বিশেষত ডিবাগ প্রিন্টফেস সম্পর্কে ছিল, সুতরাং বিনা শর্তে শ্রেণিবদ্ধ ভেরিয়েবলগুলি এখানে কোনও সমস্যা নয়। দ্বিতীয়ত, আধুনিক সংকলকগুলির ক্ষমতা দেওয়া আপনার পক্ষে যতটা সম্ভব কম পরিমাণে #ifdefs ব্যবহার করা উচিত। বেশিরভাগ ক্ষেত্রে আপনি এর পরিবর্তে বিল্ড কনফিগারেশন বা টেম্পলেট বিশেষাধিকার ব্যবহার করতে পারেন।
দিমা

0

ড্রাইভারকে শর্তসাপেক্ষ সংজ্ঞায়িত করার জন্য বিভিন্ন উপায়ে পার্থক্য রয়েছে:

diff <( echo | g++ -DA= -dM -E - ) <( echo | g++ -DA -dM -E - )

আউটপুট:

344c344
< #define A 
---
> #define A 1

এর অর্থ, এটি -DAপ্রতিশব্দ -DA=1এবং যদি মান বাদ দেওয়া হয় তবে এটি #if Aব্যবহারের ক্ষেত্রে সমস্যা হতে পারে ।


0

আমি পছন্দ করি #define DEBUG_ENABLED (0)যখন আপনি একাধিক স্তরের ডিবাগ পেতে পারেন। উদাহরণ স্বরূপ:

#define DEBUG_RELEASE (0)
#define DEBUG_ERROR (1)
#define DEBUG_WARN (2)
#define DEBUG_MEM (3)
#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL (DEBUG_RELEASE)
#endif
//...

//now not only
#if (DEBUG_LEVEL)
//...
#endif

//but also
#if (DEBUG_LEVEL >= DEBUG_MEM)
LOG("malloc'd %d bytes at %s:%d\n", size, __FILE__, __LINE__);
#endif

আপনার অন্যান্য জিনিস ডিবাগ করার ক্ষেত্রে সেই সমস্ত লগ লাইন না রেখে মেমরি ফাঁস ডিবাগ করা সহজ করে তোলে।

এছাড়াও #ifndefসংজ্ঞায়িত চারপাশে কমান্ডলাইনে একটি নির্দিষ্ট ডিবাগ স্তর বাছাই করা সহজ করে তোলে:

make -DDEBUG_LEVEL=2
cmake -DDEBUG_LEVEL=2
etc

যদি এটির জন্য না হয় তবে আমি এটিকে উপকার দেব #ifdefকারণ সংকলক / তৈরি পতাকাটি ফাইলের একটির দ্বারা ওভাররাইড হয়ে যাবে। সুতরাং আপনাকে কমিট করার আগে শিরোনামটি ফিরে পরিবর্তন করার বিষয়ে চিন্তা করতে হবে না।

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