2009-08-22 15 views
38

कृपया बताएं कि नाम क्या है, यह कैसे काम करता है, यह किस समस्या का हल करता है, और जिसमें संदर्भ और भाषाएं उपयोग की जाती हैं। नाम मैंगलिंग रणनीतियों (उदाहरण के लिए कंपाइलर द्वारा क्यों चुना जाता है और क्यों) एक प्लस।नाम उलझन क्या है, और यह कैसे काम करता है?

+3

मंगल नामों ने सी ++ के "ट्रोजन हॉर्स" इतिहास में एक भूमिका निभाई, देखें: http://ejohnson.blogs.com/software/2004/11/i_find_c_intere.html – harpo

+1

@harpo: दिलचस्प, लेकिन थोड़ा "कठोर "। मेरा मतलब है, जो कहा जाता है वह नई सुविधाओं का परिणाम है। मुझे नहीं लगता कि इसे किसी भी परिस्थिति में जानबूझकर देखा जा सकता है। –

उत्तर

35

अपनी पसंद की प्रोग्रामिंग भाषा में, यदि एक पहचानकर्ता को अलग से संकलित इकाई से निर्यात किया जाता है, तो उसे एक ऐसे नाम की आवश्यकता होती है जिसके द्वारा इसे लिंक समय पर जाना जाता है। नाम मैंगलिंग प्रोग्रामिंग भाषाओं में अधिभारित पहचानकर्ता की समस्या हल करता है। (एक पहचानकर्ता "अतिभारित" है एक ही नाम एक से अधिक संदर्भ में या एक से अधिक अर्थ के साथ प्रयोग किया जाता है।)

कुछ उदाहरण:

  • C++ में, समारोह या विधि get ओवरलोड हो गया है कई प्रकार पर।

  • एडा या मॉडुला -3 में, get फ़ंक्शन एकाधिक मॉड्यूल में दिखाई दे सकता है।

एकाधिक प्रकार और एकाधिक मॉड्यूल सामान्य संदर्भों को कवर करते हैं।

विशिष्ट रणनीतियों:

  • मानचित्र एक स्ट्रिंग के लिए प्रत्येक प्रकार के और लिंक-टाइम नाम के रूप में संयुक्त उच्च स्तरीय पहचानकर्ता और "प्रकार स्ट्रिंग" का उपयोग करें। सी ++ में आम (विशेष रूप से आसान है क्योंकि ओवरलोडिंग केवल कार्यों/विधियों और केवल तर्क प्रकारों के लिए ही अनुमति दी जाती है) और एडा (जहां आप परिणाम प्रकारों को भी अधिभारित कर सकते हैं)।

  • एक पहचानकर्ता एक से अधिक मॉड्यूल या नाम स्थान में इस्तेमाल किया जाता है, तो पहचानकर्ता का नाम, उदाहरण के लिए, List_getList.get के बजाय साथ मॉड्यूल का नाम शामिल हो।

लिंक-टाइम नामों में कौन से पात्र कानूनी हैं, इस पर निर्भर करते हुए, आपको अतिरिक्त उलझन करना पड़ सकता है; उदाहरण के लिए, यह एक 'भागने' चरित्र के रूप में अंडरस्कोर उपयोग करने के लिए आवश्यक हो सकता है, तो आप

  • List_my.get भेद कर सकते हैं - से

    • List.my_get>List__my_get

    ->List_my__get

(माना जाता है कि यह उदाहरण पहुंच रहा है, लेकिन एक के रूप में कंपाइलर लेखक, मुझे यह गारंटी देना है कि अलग-अलग लिंक-टाइम नाम पर स्रोत कोड मानचित्र में अलग-अलग पहचानकर्ता हैं। नाम उलझन के लिए यही कारण और उद्देश्य है।)

+0

उलझन वाले नाम आम तौर पर अधिक घृणित होते हैं। उदाहरण के लिए, '__ZmlRK8Matrix3fRK3Ray'' रे ऑपरेटर * (कॉन्स मैट्रिक्स 3 एफ और मैट्रिक्स, कॉन्स रे एंड ओरे) नामक मेरे फ़ंक्शन के लिए उलझन वाला नाम था। मुझे प्यार है कि कुछ लोग इसे "नाम सजावट" कहते हैं। "हाँ, मेरे पास मेरे फ़ंक्शन नाम _decorated_ होंगे, कृपया। Blargh!" – bobobobo

+0

वास्तव में बहुत उपयोगी जवाब। नाम मैंगलिंग प्रक्रिया में अंडरस्कोर के "भागने" के बारे में उदाहरण स्रोत-से-स्रोत कंपाइलर्स के लिए बहुत उपयोगी है। – Askaga

23

बस शब्दों में कहें, नाम-मैंगलिंग एक ऐसी प्रक्रिया है जिसके द्वारा संकलक linker को उन पहचानकर्ताओं के बीच असंबद्धता में सहायता के लिए आपके स्रोत कोड में पहचानकर्ताओं के नाम बदलते हैं।

Wikipedia has a wonderful article on this subject कई शानदार उदाहरणों के साथ।

4

Name mangling एक ऐसा माध्यम है जिसके द्वारा संकलक किसी ऑब्जेक्ट के "संकलित" नाम को संशोधित करते हैं, ताकि आप इसे लगातार तरीके से निर्दिष्ट कर सकें।

यह प्रोग्रामिंग भाषा को एकाधिक, संकलित वस्तुओं को समान नाम प्रदान करने की लचीलापन देता है, और उपयुक्त वस्तु को देखने के लिए एक सतत तरीका है। उदाहरण के लिए, यह एक ही नाम के साथ कई वर्गों को अलग-अलग नामस्थानों में मौजूद होने की अनुमति देता है (अक्सर नामस्थान में नामस्थान को प्रीपेड करके)।

कई भाषाओं में ऑपरेटर और विधि ओवरलोडिंग यह एक कदम आगे ले जाती है - प्रत्येक विधि एक ही नाम के साथ एक प्रकार के अस्तित्व में कई विधियों को अनुमति देने के लिए संकलित लाइब्रेरी में "उलझन" नाम के साथ समाप्त होती है।

2

पायथन में, नाम-मैंगलिंग एक ऐसी प्रणाली है जिसके द्वारा कक्षा चर के वर्ग के अंदर और बाहर अलग-अलग नाम होते हैं। प्रोग्रामर वैरिएबल नाम की शुरुआत में दो अंडरस्कोर डालकर "सक्रिय" करता है।

उदाहरण के लिए, मैं कुछ सदस्यों के साथ एक सरल वर्ग को परिभाषित कर सकते हैं:

>>> class Foo(object): 
... def __init__(self): 
... self.x = 3 
... self._y = 4 
... self.__z = 5 
... 

अजगर अभ्यास में, एक चर नाम एक अंडरस्कोर के साथ शुरू है "आंतरिक" और वर्ग इंटरफ़ेस का हिस्सा नहीं है, और इसलिए प्रोग्रामर इस पर भरोसा नहीं करना चाहिए। हालांकि, यह अभी भी दिखाई दे रहा है:

>>> f = Foo() 
>>> f.x 
3 
>>> f._y 
4 

एक चर नाम दो अंडरस्कोर के साथ शुरू अब भी जनता है, लेकिन यह उपयोग करने के लिए नाम-घायल है और इस तरह कठिन: यदि हम जानते हैं कि कैसे नाम

>>> f.__z 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'Foo' object has no attribute '__z' 

काम करता है -mangling, हालांकि, हम उस पर प्राप्त कर सकते हैं:

>>> f._Foo__z 
5 

यानी classname एक अतिरिक्त अंडरस्कोर के साथ चर नाम के लिए prepended है।

पायथन में 'निजी' बनाम 'सार्वजनिक' सदस्यों की कोई अवधारणा नहीं है; सब कुछ सार्वजनिक है। नाम-मैंगलिंग सबसे मजबूत संभव संकेत है जो एक प्रोग्रामर भेज सकता है कि चर के बाहर से चर को एक्सेस नहीं किया जाना चाहिए।

+0

यह ध्यान दिया जाना चाहिए कि पाइथन में नाम मैंगलिंग का मुख्य कारण है ["subclasses द्वारा परिभाषित नामों के नामों के नामों के नाम से बचने के लिए"] (https://docs.python.org/3/tutorial/classes.html) – dvb

0

फोरट्रान में, नाम मैंगलिंग की आवश्यकता है क्योंकि भाषा असंवेदनशील है, जिसका अर्थ है कि फू, फू, फू, फू इत्यादि .. सभी एक ही प्रतीक को हल करेंगे, जिसका नाम किसी भी तरह से सामान्यीकृत होना चाहिए। विभिन्न कंपाइलर्स अलग-अलग मैंगलिंग लागू करते हैं, और यह एक अलग संकलक के साथ संकलित सी या बाइनरी ऑब्जेक्ट्स के साथ इंटरफेसिंग करते समय बड़ी परेशानी का स्रोत है। उदाहरण के लिए, जीएनयू जी 77/जी 5 9, हमेशा एक संक्षिप्त अंडरस्कोर को लोअरकेज्ड नाम में जोड़ता है, जब तक कि नाम में पहले से ही एक या अधिक अंडरस्कोर नहीं होता है। इस मामले में, दो अंडरस्कोर जोड़े गए हैं।

उदाहरण के लिए, निम्नलिखित दिनचर्या

program test 
    end program 

    subroutine foo() 
    end subroutine 

    subroutine b_ar() 
    end subroutine 
    subroutine b_a_r() 
    end subroutine 

उत्पादन निम्नलिखित घायल प्रतीक:

0000000000400806 g  F .text 0000000000000006    b_ar__ 
0000000000400800 g  F .text 0000000000000006    foo_ 
000000000040080c g  F .text 0000000000000006    b_a_r__ 

क्रम सी से फोरट्रान कोड फोन करने के लिए, ठीक से घायल दिनचर्या नाम लागू किया जाना चाहिए (स्पष्ट रूप से ध्यान में रखते हुए खाते में वास्तव में अलग-अलग मैंगलिंग रणनीतियों को वास्तव में स्वतंत्र संकलक होना चाहिए)। फोर्टन से सी कोड को कॉल करने के लिए, एक सी-लिखित इंटरफ़ेस को ठीक से उलझन वाले नामों को निर्यात करना होगा और कॉल को सी रूटीन में अग्रेषित करना होगा। इस इंटरफ़ेस को फिर फोरट्रान से बुलाया जा सकता है।

2

स्रोत: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

नाम mangling अपने कार्यक्रम का एक अलग नाम में प्रत्येक कार्य सी ++ compilers द्वारा प्रयोग किया जाता देने वाली प्रक्रिया है। सी ++ में, आम तौर पर कार्यक्रमों में कम से कम कुछ फ़ंक्शन समान नाम होते हैं। इस प्रकार नाम mangling सी ++ में एक महत्वपूर्ण पहलू के रूप में माना जा सकता है।

उदाहरण: आम तौर पर, सदस्य नाम वर्ग के साथ सदस्य के नाम को जोड़कर विशिष्ट रूप से उत्पन्न होते हैं। घोषणा को देखते हुए:

class Class1 
{ 
     public: 
      int val; 
      ... 
    }; 

वैल हो जाता है कुछ की तरह:

// a possible member name mangling 
    val__11Class1 
0

वस्तु उन्मुख भाषा के अधिकांश समारोह ओवरलोडिंग सुविधा प्रदान करते हैं। फ़ंक्शन ओवरलोडिंग यदि किसी वर्ग में समान नामों के साथ कई फ़ंक्शन हैं लेकिन विभिन्न पैरामीटर & नंबर टाइप करते हैं तो उन्हें ओवरलोड किया जाता है। फ़ंक्शन ओवरलोडिंग आपको विभिन्न कार्यों के लिए समान नाम का उपयोग करने की अनुमति देती है।

तरीके एक समारोह

  1. ओवरलोड तर्क की संख्या बदल कर।
  2. सूची आइटम विभिन्न प्रकार के तर्क होने के द्वारा।

नाम मैंगलिंग के साथ कार्य ओवरलोडिंग कैसे प्राप्त की जाती है?
सी ++ कंपाइलर ऑब्जेक्ट कोड उत्पन्न करते समय विभिन्न कार्यों के बीच अंतर करता है - यह प्रकार और तर्कों की संख्या के आधार पर तर्कों के बारे में जानकारी जोड़कर नाम बदलता है। फ़ंक्शन नाम बनाने के लिए अतिरिक्त जानकारी जोड़ने की यह तकनीक नाम Mangling कहा जाता है। सी ++ मानक नाम मैंगलिंग के लिए कोई विशेष तकनीक निर्दिष्ट नहीं करता है, इसलिए अलग-अलग कंपाइलर फ़ंक्शन नामों पर अलग-अलग जानकारी जोड़ सकते हैं। मैंने gcc4.8.4 पर नमूना प्रोग्राम चलाया है।

class ABC 
{  
public: 
    void fun(long a, long b) {} 
    void fun(float a, float b) {} 
    void fun(int a, float b) {} 
}; 
int main() 
{ 
ABC obj; 
obj.fun(1l,2l); 
obj.fun(1,2.3f); 
obj.fun(3.2f,4.2f); 
return 0; 
} 

इस कार्यक्रम में 3 कार्यों को मज़ेदार नाम दिया गया है जिसमें तर्क और उनके प्रकारों के आधार पर भिन्नता है। इन कार्यों के नाम के नीचे के रूप में घायल कर रहे हैं:

[email protected]:~$ nm ./a.out |grep fun 
000000000040058c W _ZN3ABC3funEff 
00000000004005a0 W _ZN3ABC3funEif 
000000000040057a W _ZN3ABC3funEll 
  • एबीसी वर्ग के नाम के लिए कमांड स्ट्रिंग है
  • मजेदार है समारोह नाम
  • एफएफ दो float-> तर्क का प्रकार च के लिए आम स्ट्रिंग
  • दो लंबे-> एल टाइपऑफ तर्क
  • यदि पहला पूर्णांक तर्क-> मैं और एक फ्लोट-> एफ तर्क
0

उस समय लिंक संपादक को डिज़ाइन किया गया था, सी, फोर्टन और कोबोल जैसी भाषाओं में नामस्थान, कक्षाएं, कक्षाओं के सदस्य और ऐसी अन्य चीजें नहीं थीं। ऑब्जेक्ट उन्मुख सुविधाओं का समर्थन करने के लिए नाम मैंगलिंग की आवश्यकता होती है जैसे लिंक संपादक वाले जो उन्हें समर्थन नहीं देते हैं।तथ्य यह है कि लिंक संपादक अतिरिक्त सुविधाओं का समर्थन नहीं करता है अक्सर याद किया जाता है; लोग यह कहते हुए इसका मतलब देते हैं कि लिंक संपादक के कारण नाम उलझन की आवश्यकता है।

चूंकि मैंगलिंग के नाम का समर्थन करने के लिए भाषा आवश्यकताओं के बीच बहुत अधिक भिन्नता है, इसलिए लिंक संपादक में इसका समर्थन करने की समस्या का कोई आसान समाधान नहीं है। लिंक संपादकों को विभिन्न प्रकार के कंपाइलरों से आउटपुट (ऑब्जेक्ट मॉड्यूल) के साथ काम करने के लिए डिज़ाइन किया गया है और इसलिए नामों का समर्थन करने के लिए एक सार्वभौमिक तरीका होना चाहिए।

संबंधित मुद्दे