যদি-দিকনির্দেশক ম্যাক্রোর তুলনা


25

#ifনিম্নলিখিত কোডের শর্তটি কেন পূরণ করা হয়েছে:

#include <iostream>
#define VALUE foo    

int main() {    
#if VALUE == bar
    std::cout << "WORKS!" << std::endl;
#endif // VALUE
}

উত্তর:


26

Cppreference.com পৃষ্ঠার পদ বলে:

সমস্ত ম্যাক্রো প্রসারিত এবং নির্ধারিত এবং __হাস_ইনক্লিন্ড (সি ++ 17) প্রকাশের মূল্যায়নের পরে, কোনও বুলিয়ান আক্ষরিক নয় এমন কোনও শনাক্তকারীকে 0 নম্বর দিয়ে প্রতিস্থাপন করা হবে (এতে শনাক্তকারীগুলি অন্তর্ভুক্ত রয়েছে যা বর্ণবাদী কীওয়ার্ড, তবে বিকল্প টোকেনগুলি পছন্দ করে না এবং )।

সুতরাং উভয় fooএবং bar0 দিয়ে প্রতিস্থাপিত হয়।


সি ++ 98, সি ++ 03, সি ++ 11 এবং সি ++ 14 সম্পর্কে কী?
কেলালাকা

1
@ কেলালাকা সব কিছু একরকম। এটি C89 সাল থেকে এখনও সেভাবেই ছিল।
এসএস অ্যান

1
@ কোলালাকা "যেহেতু সি ++ 17" কেবলমাত্র "এবং __হাস_মিল" অংশটি বোঝায়। সি ++ 17 এর আগে এটি একই ছিল, কেবলমাত্র সেই অংশটি বাদ দেওয়া হয়েছিল।
BessieTheCow

15

একটি #ifবিবৃতিতে, কোনও সনাক্তকারী যা ম্যাক্রো প্রতিস্থাপনের পরে অবধি থাকে (বাদে trueএবং ব্যতীত false) ধ্রুবক দ্বারা প্রতিস্থাপিত হয় 0। সুতরাং আপনার নির্দেশিকা হয়ে যায়

#if 0 == 0

কোনটা সত্য.


স্পষ্ট করার জন্য, '#
ডিফাইন ভ্যালু ফু

13

এর কারণ তন্ন তন্ন fooনা barকোন সংজ্ঞা বা মূল্য দেওয়া হয়েছে - তাই তারা একই (অর্থাত একটি "0" মান প্রয়োগ করা হবে)। সংকলকগণ এ সম্পর্কে সতর্কতা দেবেন।

MSVCকম্পাইলার (ভিসুয়াল স্টুডিও 2019) নিম্নলিখিত দেয়:

সতর্কতা C4668: 'foo' প্রিপ্রোসেসর ম্যাক্রো হিসাবে সংজ্ঞায়িত করা হয়নি, '# যদি / #
এলিফ ' সতর্কতা C4668: 'বার' প্রিপ্রসেসর ম্যাক্রো হিসাবে সংজ্ঞায়িত করা হয় না তবে '0' এর পরিবর্তে '#' / # Elif '

সুতরাং VALUEমান '0' (এর জন্য ডিফল্ট foo) দেওয়া হয় এবং bar' VALUE == bar0'ও রয়েছে , সুতরাং "সত্য" এ মূল্যায়ন করুন।

একইভাবে, clang-clনিম্নলিখিত দেয়:

সতর্কতা: 'foo' সংজ্ঞায়িত করা হয় না, 0 [-উন্ডফ]
সতর্কতার জন্য মূল্যায়ন করে : 'বার' সংজ্ঞায়িত হয় না, 0 -কে মূল্যায়ন করে [-উন্ডফ]


সতর্কবাণী বাধ্যতামূলক বা এটি সংকলকগুলির একটি বৈশিষ্ট্য?
কেলালাকা

1
@ কেলালাকা আমার জ্ঞানের সর্বোপরি, কোনও সংকলক 'সতর্কতা' বাধ্যতামূলক নয়! এমনকি MSVCএবং clang-clসংকলকগুলির সাথেও , এই সতর্কতা অক্ষম করা যেতে পারে (হয় বিশেষভাবে, বা একটি উপযুক্ত সতর্কতা 'স্তর' সেট করে)।
অ্যাড্রিয়ান মোল

0

আপনার পরে যা আছে তা অর্জন করতে, এটি চেষ্টা করুন:

#include <iostream>
#define DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

এই ক্ষেত্রে আপনি ডিবাগিং স্টেটমেন্টগুলি "সংজ্ঞায়িত" কে "অপরিবর্তিত" পরিবর্তন করে বন্ধ করতে পারেন।

#include <iostream>
#undef DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

আপনি দেখতে পাচ্ছেন যে আপনার সংকলক আপনাকে কোডের বাইরেই ডিইবিইউজি সংজ্ঞায়িত করার অনুমতি দেয়, সেই সময়ে আপনি কোডটি হ্রাস করতে পারবেন

#include <iostream>

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

এবং তারপরে একটি বিকল্প যেমন -DDEBUG = 0 এর সাথে সংকলককে অনুরোধ করুন

স্টিভ ম্যাককনেলের ডিফেন্সিভ প্রোগ্রামিং সম্পর্কিত অধ্যায়টি দেখুন, "কোড সম্পূর্ণ।"

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