इस लाइन का क्या अर्थ है? विशेष रूप से, ##
का क्या अर्थ है?##fine मतलब में ## क्या है?
#define ANALYZE(variable, flag) ((Something.##variable) & (flag))
संपादित करें:
थोड़ा सा अभी भी उलझन में। परिणाम ##
के बिना क्या होगा?
इस लाइन का क्या अर्थ है? विशेष रूप से, ##
का क्या अर्थ है?##fine मतलब में ## क्या है?
#define ANALYZE(variable, flag) ((Something.##variable) & (flag))
संपादित करें:
थोड़ा सा अभी भी उलझन में। परिणाम ##
के बिना क्या होगा?
A little bit confused still. What will the result be without ##?
आमतौर पर आपको कोई अंतर दिखाई नहीं होंगे।लेकिन एक अंतर है। मान लीजिए कि Something
प्रकार का है:
struct X { int x; };
X Something;
और देखो: टोकन संयोजन ऑपरेटर ##
बिना
int X::*p = &X::x;
ANALYZE(x, flag)
ANALYZE(*p, flag)
, वह फैलता करने के लिए:
#define ANALYZE(variable, flag) ((Something.variable) & (flag))
((Something. x) & (flag))
((Something. *p) & (flag)) // . and * are not concatenated to one token. syntax error!
टोकन संयोजन के साथ
इसे करने के लिए फैलता है:
#define ANALYZE(variable, flag) ((Something.##variable) & (flag))
((Something.x) & (flag))
((Something.*p) & (flag)) // .* is a newly generated token, now it works!
यह याद रखना महत्वपूर्ण है कि प्रीप्रोसेसर प्रीप्रोसेसर टोकन, पर पाठ पर पर काम करता है। तो यदि आप दो टोकन को जोड़ना चाहते हैं, तो आपको स्पष्ट रूप से यह कहना होगा।
पर विचार
#define MYMACRO(x,y) x##y
##
बिना, स्पष्ट रूप से नहीं कर सकते पूर्वप्रक्रमक अलग टोकन के रूप में x
और y
देखते हैं, यह कर सकते हैं:
##
टोकन कॉन्सटेनेशन कहा जाता है, जो एक मैक्रो आमंत्रण में दो टोकन को संयोजित करने के लिए उपयोग किया जाता है।
इस देखें:
वास्तव में इसे टोकन कॉन्सटेनेशन कहा जाता है। मुझे नहीं लगता कि आईबीएम एईक्स सी/सी ++ कंपाइलर के लिए प्रलेखन सबसे अच्छा संदर्भ है! –
@ डेविड: इसे मेरे उत्तर में जोड़ा गया। धन्यवाद :-) – Nawaz
@ डेविड: मैंने यह नहीं कहा कि आईबीएम एईक्स सी/सी ++ कंपाइलर सबसे अच्छा संदर्भ है। सर्वश्रेष्ठ संदर्भ मानक के अलावा कुछ भी नहीं है। लेकिन हम स्टैक ओवरफ्लो पर विषयों सहित वैसे भी अन्य साइटों के लिंक देते हैं। – Nawaz
विकिपीडिया के अनुसार
Token concatenation, also called token pasting, is one of the most subtle — and easy to abuse — features of the C macro preprocessor. Two arguments can be 'glued' together using ## preprocessor operator; this allows two tokens to be concatenated in the preprocessed code. This can be used to construct elaborate macros which act like a crude version of C++ templates.
एक बहुत महत्वपूर्ण बात यह है कि इस टोकन संयोजन कुछ बहुत ही खास नियमों का पालन करती है :
उदा। आईबीएम दस्तावेज़:
ArgArg(lady, bug) "ladybug"
ArgText(con) "conTEXT"
TextArg(book) "TEXTbook"
TextText "TEXTtext"
ArgArg(Jitter, bug) 3
स्रोत आईबीएम प्रलेखन है:
उदाहरण भी बहुत स्वयं
#define ArgArg(x, y) x##y
#define ArgText(x) x##TEXT
#define TextArg(x) TEXT##x
#define TextText TEXT##text
#define Jitter 1
#define bug 2
#define Jitterbug 3
उत्पादन के साथ
समझा रहे हैं। अन्य कंपाइलर्स के साथ भिन्न हो सकता है।
अपनी लाइन के लिए : "। समथिंग"
यह करने के लिए चर विशेषता concatenates और एक वेरिएबल को एड्रेस करता है जो तार्किक रूप से एंडेड होता है जो परिणामस्वरूप देता है अगर Something.variable में ध्वज सेट है।
तो मेरा आखिरी टिप्पणी और अपने प्रश्न (छ साथ compileable ++) के लिए एक उदाहरण:
// this one fails with a compiler error
// #define ANALYZE1(variable, flag) ((Something.##variable) & (flag))
// this one will address Something.a (struct)
#define ANALYZE2(variable, flag) ((Something.variable) & (flag))
// this one will be Somethinga (global)
#define ANALYZE3(variable, flag) ((Something##variable) & (flag))
#include <iostream>
using namespace std;
struct something{
int a;
};
int Somethinga = 0;
int main()
{
something Something;
Something.a = 1;
if (ANALYZE2(a,1))
cout << "Something.a is 1" << endl;
if (!ANALYZE3(a,1))
cout << "Somethinga is 0" << endl;
return 1;
};
एक अलग उदाहरण पर विचार की सुविधा देता है?
अपने उदाहरण में,
#define ANALYZE(variable, flag) ((Something.##variable) & (flag))
##
बस के रूप में आप किसी भी नए पहचानकर्ता नहीं कर रहे हैं की जरूरत नहीं है। वास्तव में, कंपाइलर समस्याएं "त्रुटि: चिपकाना"। "और" परिवर्तनीय "वैध प्रीप्रोकैसिंग टोकन नहीं देता है"
यह आपके प्रश्न का उत्तर नहीं है, केवल कुछ सीपीयू पोस्ट प्रीप्रोसेसर का पता लगाने में आपकी सहायता के लिए स्वयं।
प्रीप्रोकैसिंग चरण वास्तव में संकलित किए गए किसी भी वास्तविक कोड से पहले किया जाता है। दूसरे शब्दों में, जब संकलक आपके कोड का निर्माण शुरू करता है, तो #define कथन या उसके जैसा कुछ भी शेष है।
प्रीप्रोसेसर आपके कोड पर क्या करता है यह समझने का एक अच्छा तरीका है प्रीप्रोसेस्ड आउटपुट को पकड़ना और इसे देखना।
यह कैसे विंडोज के लिए यह करने के लिए है:
एक सरल test.cpp बुलाया फ़ाइल बनाएँ और उसे फ़ोल्डर में रख दें, कहते हैं कि c: \ अस्थायी। मेरा इस तरह दिखता है:
#define dog_suffix(variable_name) variable_name##dog
int main()
{
int dog_suffix(my_int) = 0;
char dog_suffix(my_char) = 'a';
return 0;
}
बहुत उपयोगी नहीं है, लेकिन सरल। विजुअल स्टूडियो कमांड प्रॉम्प्ट खोलें, फ़ोल्डर में नेविगेट और निम्नलिखित कमांडलाइन चलाएँ:
c:\temp>cl test.cpp /P
इसलिए, यह संकलक अपने चल (cl.exe), अपनी फ़ाइल के साथ है, और/पी विकल्प को संकलक बताता है preprocessed आउटपुट को एक फाइल में स्टोर करें।
अब test.cpp के बगल में स्थित फ़ोल्डर में आपको परीक्षण मिलेगा।मैं, जो मेरे लिए इस तरह दिखता है:
#line 1 "test.cpp"
int main()
{
int my_intdog = 0;
char my_chardog = 'a';
return 0;
}
आप देख सकते हैं, कोई #define बाईं, केवल कोड में विस्तार किया।
यह भी देखें: http://stackoverflow.com/questions/1597007/creating-c-macro-with-and-line-token-concatenation-with-positioning-macro – sharkin