अनाम / अनाम नाम बनाम स्थिर कार्य


507

C ++ की एक विशेषता अनाम (अनाम) नामस्थान बनाने की क्षमता है, जैसे:

namespace {
    int cannotAccessOutsideThisFile() { ... }
} // namespace

आपको लगता है कि इस तरह की सुविधा बेकार होगी - चूंकि आप नाम स्थान का नाम निर्दिष्ट नहीं कर सकते हैं, इसलिए इसके भीतर कुछ भी बाहर तक पहुंचना असंभव है। लेकिन इन अनाम नामस्थान हैं , वे में बनाया कर रहे हैं फ़ाइल के भीतर सुलभ के रूप में अगर आप उन्हें एक अंतर्निहित का उपयोग कर-खंड था।

मेरा प्रश्न यह है कि स्थैतिक कार्यों का उपयोग करना क्यों या कब तक बेहतर होगा? या वे वास्तव में एक ही काम करने के दो तरीके हैं?


13
C ++ 11 staticमें इस संदर्भ का उपयोग पूर्ववत था ; हालांकि अनाम नेमस्पेस एक बेहतर विकल्प हैstatic , लेकिन ऐसे उदाहरण हैं जहां यह staticबचाव में आता है
लीजेंड

जवाबों:


332

C ++ मानक खंड .1.३.१.१ में पढ़ता है नामस्थान, पैरा २:

स्थैतिक कीवर्ड का उपयोग तब किया जाता है जब किसी नेमस्पेस स्कोप में वस्तुओं की घोषणा की जाती है, अनाम-नेमस्पेस एक बेहतर विकल्प प्रदान करता है।

स्टेटिक केवल वस्तुओं, कार्यों और अनाम यूनियनों के नामों पर लागू होता है, न कि घोषणाओं को टाइप करने के लिए।

संपादित करें:

स्थैतिक कीवर्ड के इस उपयोग को चित्रित करने का निर्णय (अनुवाद इकाई में एक चर घोषणा की दृश्यता को प्रभावित) को उलट दिया गया है ( रेफरी )। इस मामले में एक स्थिर या अनाम नाम स्थान का उपयोग करते हुए वास्तव में एक ही काम करने के दो तरीके हैं। अधिक चर्चा के लिए कृपया इस SO प्रश्न को देखें ।

वॉशस्पेस में अनुवाद-इकाई-स्थानीय प्रकारों को परिभाषित करने की अनुमति देने का लाभ अभी भी है। अधिक विवरण के लिए कृपया इस SO प्रश्न को देखें।

मेरे ध्यान में इसे लाने का श्रेय माइक पर्सी को जाता है ।


39
हेड गीक केवल कार्यों के खिलाफ उपयोग किए जाने वाले स्थिर कीवर्ड के बारे में पूछता है। नेमस्पेस स्कोप में घोषित एंटिटी पर लागू स्थिर कीवर्ड इसकी आंतरिक लिंकेज को निर्दिष्ट करता है। अनाम नेमस्पेस में घोषित एंटिटी में बाहरी लिंकेज (C ++ / 3.5) है, हालांकि इसे विशिष्ट रूप से नामित दायरे में रहने की गारंटी है। अनाम नाम स्थान की यह गुमनामी प्रभावी रूप से इसकी घोषणा को छुपा देती है, जो इसे केवल अनुवाद इकाई के भीतर से सुलभ बनाती है। बाद वाला प्रभावी रूप से स्थैतिक कीवर्ड के समान कार्य करता है।
mloskot

5
बाहरी लिंकेज की खामी क्या है? क्या यह इनलाइनिंग को प्रभावित कर सकता है?
एलेक्स

17
C ++ डिज़ाइन कॉमेटी में जिन्होंने कहा कि स्थैतिक कीवर्ड को पदावनत किया जाता है, उन्होंने शायद एक बड़ी वास्तविक दुनिया प्रणाली में एक विशाल C कोड के साथ कभी काम नहीं किया है ... (यदि आप स्थैतिक रूप से एक स्थिर कीवर्ड देखते हैं, लेकिन अनाम नाम स्थान नहीं है, तो इसमें बड़ी टिप्पणी के साथ बहुत कुछ है। ब्लॉक।)
कैलमेरियस

23
क्योंकि यह उत्तर Google पर "c ++ अनाम नाम स्थान" के लिए एक शीर्ष परिणाम के रूप में आता है, इसलिए यह ध्यान दिया जाना चाहिए कि स्थैतिक का उपयोग अब नहीं किया जाता है। देखें stackoverflow.com/questions/4726570/... और open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1012 अधिक जानकारी के लिए।
माइकल पर्सी

2
@ErikAronesty जो गलत लगती है। क्या आपके पास एक प्रजनन योग्य उदाहरण है? C ++ 11 के अनुसार - और इससे पहले भी कुछ कंपाइलरों में - अनाम namespaceएस का निहितार्थ आंतरिक संबंध है, इसलिए कोई अंतर नहीं होना चाहिए। जो भी मुद्दे पहले खराब हो सकते थे, उन्हें C ++ 11 में एक आवश्यकता बनाकर हल किया गया था।
अंडरस्कोर_ड

73

एक अनाम नेमस्पेस में विधियाँ डालना आपको गलती से वन डेफिनिशन नियम का उल्लंघन करने से रोकता है , जिससे आप कभी भी अपने सहायक तरीकों के नामकरण के बारे में चिंता नहीं कर सकते हैं जैसा कि आप किसी अन्य विधि से लिंक कर सकते हैं।

और, जैसा कि ल्यूक द्वारा बताया गया है, अनाम नाम स्थान स्थिर सदस्यों से अधिक मानक द्वारा पसंद किए जाते हैं।


2
मैं स्टैटिक स्टैंड-अलोन फ़ंक्शंस (यानी फ़ाइल-स्कॉप्ड फ़ंक्शंस) की बात कर रहा था, स्टैटिक मेंबर फ़ंक्शंस की नहीं। स्टैटिक स्टैंड-अलोन फ़ंक्शंस एक अनाम नेमस्पेस में फ़ंक्शंस के समान ही होते हैं, इस प्रकार प्रश्न।
हेड गीक

2
आह; ठीक है, ODR अभी भी लागू होता है। पैराग्राफ हटाने का संपादन किया।
खतरा

जैसा कि मुझे मिलता है, स्थैतिक फ़ंक्शन के लिए ODR तब काम नहीं करता है जब इसे हेडर में परिभाषित किया गया हो और यह हेडर एक से अधिक अनुवाद इकाई में शामिल हो, सही? इस मामले में आपको एक ही फ़ंक्शन की कई प्रतियां प्राप्त होती हैं
एंड्री टाइक्लेको

@Andy T: शामिल किए गए हेडर के मामले में आप वास्तव में "कई परिभाषाएं" नहीं देखते हैं। प्रीप्रोसेसर इसकी देखभाल करता है। जब तक कि प्रीप्रोसेसर ने जो आउटपुट उत्पन्न किया है, उसका अध्ययन करने की आवश्यकता है, जो मुझे विदेशी और दुर्लभ लगती है। इसके अलावा हेडर फ़ाइलों में "गार्ड" को शामिल करने के लिए एक अच्छा अभ्यास है, जैसे: "#ifndef SOME_GUARD - #define SOME_GUARD ..." जो प्रीप्रोसेसर को एक ही हेडर को दो बार शामिल करने से रोकने वाला है।
निकिता वोरोत्सोव

@NikitaVorontsov गार्ड एक ही हेडर को एक ही अनुवाद इकाई में शामिल करने से रोक सकता है, हालाँकि यह विभिन्न अनुवाद इकाइयों में कई परिभाषाएँ देता है। यह लाइन के नीचे "एकाधिक परिभाषाओं" लिंकर त्रुटि का कारण हो सकता है।
एलेक्स

37

एक किनारे का मामला है जहां स्थिर का आश्चर्यजनक प्रभाव है (कम से कम यह मेरे लिए था)। 14.6.4.2/1 में C ++ 03 मानक राज्य:

फ़ंक्शन कॉल के लिए जो टेम्पलेट पैरामीटर पर निर्भर करता है, यदि फ़ंक्शन नाम एक अयोग्य-आईडी है, लेकिन टेम्प्लेट-आईडी नहीं है , तो उम्मीदवार फ़ंक्शन सामान्य लुकअप नियमों (3.4.1, 3.4.2) का उपयोग करते हुए पाए जाते हैं:

  • अयोग्य नाम लुकअप (3.4.1) का उपयोग करते हुए लुकअप के भाग के लिए, केवल टेम्प्लेट डेफिनिशन संदर्भ से बाहरी लिंकेज के साथ फ़ंक्शन घोषणाएं पाई जाती हैं।
  • संबंधित नाम स्थान (3.4.2) का उपयोग करते हुए लुकअप के भाग के लिए, केवल बाहरी लिंकेज के साथ फ़ंक्शन की घोषणाएं या तो टेम्पलेट परिभाषा संदर्भ या टेम्पलेट तात्कालिकता संदर्भ में पाई जाती हैं।

...

नीचे दिया गया कोड कॉल करेगा foo(void*)और foo(S const &)जैसा आप उम्मीद कर सकते हैं वैसा नहीं ।

template <typename T>
int b1 (T const & t)
{
  foo(t);
}

namespace NS
{
  namespace
  {
    struct S
    {
    public:
      operator void * () const;
    };

    void foo (void*);
    static void foo (S const &);   // Not considered 14.6.4.2(b1)
  }

}

void b2()
{
  NS::S s;
  b1 (s);
}

अपने आप में यह शायद इतना बड़ा सौदा नहीं है, लेकिन यह इस बात पर प्रकाश डालता है कि पूरी तरह से आज्ञाकारी C ++ कंपाइलर (यानी जिसके लिए समर्थन के साथ export) staticकीवर्ड में अभी भी कार्यक्षमता है जो किसी अन्य तरीके से उपलब्ध नहीं है।

// bar.h
export template <typename T>
int b1 (T const & t);

// bar.cc
#include "bar.h"
template <typename T>
int b1 (T const & t)
{
  foo(t);
}

// foo.cc
#include "bar.h"
namespace NS
{
  namespace
  {
    struct S
    {
    };

    void foo (S const & s);  // Will be found by different TU 'bar.cc'
  }
}

void b2()
{
  NS::S s;
  b1 (s);
}

यह सुनिश्चित करने का एकमात्र तरीका है कि हमारे अनाम नामस्थान में फ़ंक्शन ADL का उपयोग करके टेम्पलेट में नहीं मिलेगा, इसे बनाना है static

आधुनिक सी ++ के लिए अद्यतन

C ++ '11 के अनुसार, एक अनाम नाम स्थान के सदस्यों के आंतरिक संबंध (3.5 / 4) हैं:

एक अनाम नेमस्पेस या एक नेमस्पेस एक अनाम नेमस्पेस के भीतर प्रत्यक्ष या अप्रत्यक्ष रूप से घोषित किया आंतरिक संबंध है।

लेकिन एक ही समय में 14.6.4.2/1 को लिंकेज का उल्लेख हटाने के लिए अपडेट किया गया था (यह C ++ '14 से लिया गया है):

फ़ंक्शन कॉल के लिए जहां पोस्टफ़िक्स-एक्सप्रेशन एक आश्रित नाम है, उम्मीदवार फ़ंक्शन सामान्य लुकअप नियमों (3.4.1, 3.4.2) का उपयोग करते हुए पाए जाते हैं:

  • अयोग्य नाम लुकअप (3.4.1) का उपयोग करते हुए लुकअप के हिस्से के लिए, केवल टेम्प्लेट डेफिनिशन संदर्भ से फ़ंक्शन घोषणाएं पाई जाती हैं।

  • संबद्ध नामस्थान (3.4.2) का उपयोग करते हुए लुकअप के भाग के लिए, केवल फ़ंक्शन घोषणाएँ टेम्पलेट परिभाषा संदर्भ या टेम्पलेट तात्कालिकता संदर्भ में पाए जाते हैं।

परिणाम यह है कि स्थिर और अनाम नाम स्थान के सदस्यों के बीच यह विशेष अंतर अब मौजूद नहीं है।


3
क्या निर्यात कीवर्ड को ठंडा नहीं माना जाएगा? "निर्यात" का समर्थन करने वाले एकमात्र कंपाइलर प्रयोगात्मक हैं, और जब तक आश्चर्य की बात नहीं है, अप्रत्याशित दुष्प्रभावों के कारण दूसरों में "निर्यात" भी लागू नहीं किया जाएगा (ऐसा नहीं करने के अलावा यह अपेक्षित नहीं था)
पियरसबल


3
एडिसन डिज़ाइन ग्रुप (EDG) का फ्रंट-एंड कुछ भी है लेकिन प्रायोगिक है। यह निश्चित रूप से दुनिया में C ++ कार्यान्वयन के लिए सबसे मानक मानक है। Intel C ++ कंपाइलर EDG का उपयोग करता है।
रिचर्ड कॉर्डन

1
क्या C ++ सुविधा में 'अप्रत्याशित दुष्प्रभाव' नहीं हैं? निर्यात के मामले में, यह है कि एक अनाम नेमस्पेस फ़ंक्शन एक अलग टीयू से मिलेगा - यह उसी तरह है जैसे कि आपने सीधे टेम्पलेट की परिभाषा को शामिल किया था। यह इस तरह नहीं था तो और अधिक आश्चर्य होगा!
रिचर्ड कॉर्डन

मुझे लगता है कि आपके पास एक टाइपो है - NS::Sकाम करने के लिए, Sअंदर नहीं होने की जरूरत है namespace {}?
एरिक

12

मैंने हाल ही में अपने कोड में अनाम नामस्थानों के साथ स्थैतिक कीवर्ड को बदलना शुरू किया, लेकिन तुरंत एक समस्या में भाग गया जहां नामस्थान में चर अब मेरे डीबगर में निरीक्षण के लिए उपलब्ध नहीं थे। मैं VC60 का उपयोग कर रहा था, इसलिए मुझे नहीं पता कि यह अन्य डिबगर्स के साथ एक गैर-मुद्दा है। मेरा वर्कअराउंड एक 'मॉड्यूल' नामस्थान को परिभाषित करना था, जहां मैंने इसे अपनी सीपीपी फ़ाइल का नाम दिया।

उदाहरण के लिए, मेरे XmlUtil.cpp फ़ाइल में, मैं XmlUtil_I { ... }अपने सभी मॉड्यूल चर और कार्यों के लिए एक नाम स्थान परिभाषित करता हूं। इस तरह मैं XmlUtil_I::चर तक पहुँचने के लिए डिबगर में योग्यता को लागू कर सकता हूं । इस मामले में, _Iइसे सार्वजनिक नामस्थान से अलग करता है जैसे XmlUtilकि मैं कहीं और उपयोग करना चाहता हूं।

मुझे लगता है कि सही मायने में अनाम की तुलना में इस दृष्टिकोण का एक संभावित नुकसान यह है कि कोई अन्य मॉड्यूल में नेमस्पेस क्वालीफायर का उपयोग करके वांछित स्थिर दायरे का उल्लंघन कर सकता है। मैं नहीं जानता कि अगर यह एक प्रमुख चिंता का विषय है।


7
मैंने यह भी किया है, लेकिन साथ ही #if DEBUG namespace BlahBlah_private { #else namespace { #endif, इसलिए "मॉड्यूल नेमस्पेस" केवल डिबग बिल्ड में मौजूद है और सच्चे अनाम नाम स्थान का अन्यथा उपयोग किया जाता है। अच्छा होगा अगर डिबगर्स ने इसे संभालने का अच्छा तरीका दिया। इससे भी ऑक्सीजन गड़बड़ हो जाती है।
क्रिस्टोफर जॉनसन

4
अनाम नाम स्थान वास्तव में स्थैतिक के लिए एक व्यवहार्य प्रतिस्थापन नहीं है। स्थैतिक का अर्थ है "वास्तव में यह टीयू के लिंक किए गए ideide से कभी नहीं मिलता है"। अनाम नामस्थान का अर्थ है "यह अभी भी निर्यात किया जाता है, एक यादृच्छिक नाम के रूप में, अगर यह एक मूल वर्ग से बुलाया जाता है जो TU के बाहर है" ...
Erik Aronesty

7

उस उद्देश्य के लिए स्थैतिक कीवर्ड का उपयोग C ++ 98 मानक द्वारा हटा दिया गया है। स्थैतिक के साथ समस्या यह है कि यह टाइप परिभाषा पर लागू नहीं होता है। यह विभिन्न संदर्भों में अलग-अलग तरीकों से उपयोग किया जाने वाला एक अतिभारित कीवर्ड भी है, इसलिए अनाम नामस्थान चीजों को थोड़ा सरल करते हैं।


1
यदि आप किसी एकल अनुवाद इकाई में केवल एक प्रकार का उपयोग करना चाहते हैं तो इसे .cpp फ़ाइल के अंदर घोषित करें। यह वैसे भी अन्य अनुवाद इकाइयों से सुलभ नहीं होगा।
कालमेरी

4
आप सोचेंगे, क्या आप नहीं? लेकिन अगर एक ही एप्लिकेशन में एक और अनुवाद इकाई (= cpp-file) कभी भी एक ही नाम के साथ एक प्रकार की घोषणा करता है, तो आप मुश्किल-से-डिबग समस्याओं के लिए हैं :-)। उदाहरण के लिए, आप उन स्थितियों के साथ समाप्त हो सकते हैं जहां एक प्रकार की व्यवहार्यता का उपयोग दूसरे पर कॉल करने के तरीकों के लिए किया जाता है।
avl_sweden

1
अब वंचित नहीं है। और प्रकार डीईएस निर्यात नहीं किया जाता है, इसलिए यह अर्थहीन है। स्टैटिक्स स्टैंडअलोन कार्यों और वैश्विक संस्करणों के लिए उपयोगी हैं। अनाम नामस्थान कक्षाओं के लिए उपयोगी हैं।
एरिक एरोनसिटी

6

अनुभव से, मैं सिर्फ यह नोट करूंगा कि जब यह पूर्व नामी कार्यों को अनाम नाम स्थान पर रखने का C ++ तरीका है, तो पुराने कंपाइलर्स को कभी-कभी इससे समस्या हो सकती है। मैं वर्तमान में हमारे लक्ष्य प्लेटफार्मों के लिए कुछ संकलक के साथ काम करता हूं, और अधिक आधुनिक लिनक्स संकलक अनाम नाम स्थान में फ़ंक्शन रखने के साथ ठीक है।

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


3

इसके अलावा यदि कोई इस तरह के चर पर स्थिर कीवर्ड का उपयोग करता है:

namespace {
   static int flag;
}

इसे मैपिंग फ़ाइल में नहीं देखा जाएगा


7
फिर आपको अनाम नामस्थान की आवश्यकता नहीं है।
कैलमेरियस

2

अनाम नाम स्थान और स्थिर कार्यों के बीच एक संकलक विशिष्ट अंतर को निम्न कोड को संकलित करते हुए देखा जा सकता है।

#include <iostream>

namespace
{
    void unreferenced()
    {
        std::cout << "Unreferenced";
    }

    void referenced()
    {
        std::cout << "Referenced";
    }
}

static void static_unreferenced()
{
    std::cout << "Unreferenced";
}

static void static_referenced()
{
    std::cout << "Referenced";
}

int main()
{
    referenced();
    static_referenced();
    return 0;
}

इस कोड को VS 2017 के साथ संकलित करना (C4505 चेतावनी को सक्षम करने के लिए स्तर 4 चेतावनी ध्वज / W4 निर्दिष्ट करना : अपरिचित स्थानीय फ़ंक्शन हटा दिया गया है ) और 4.9 के साथ -Wunused-function या -Wall ध्वज दिखाता है कि VS 2017 केवल चेतावनी के लिए उत्पादन करेगा अप्रयुक्त स्थिर कार्य। 4.9 और उच्चतर, साथ ही साथ 3.3 और उच्चतर, नाम स्थान में अपरिवर्तित फ़ंक्शन के लिए चेतावनी का उत्पादन करेगा और अप्रयुक्त स्थिर फ़ंक्शन के लिए एक चेतावनी भी देगा।

जीसीसी 4.9 और एमएसवीसी 2017 का लाइव डेमो


2

निम्नलिखित कारणों से व्यक्तिगत रूप से मैं नाममात्र के नाम स्थान पर स्थिर कार्य पसंद करता हूं:

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

  • नामस्थानों के कार्यों को कुछ (पुराने) संकलक द्वारा बाहरी के रूप में माना जा सकता है। VS2017 में वे अभी भी बाहरी हैं। इस कारण से भी यदि कोई फ़ंक्शन नाम रहित नाम स्थान पर है, तो भी आप उन्हें स्थैतिक चिह्नित करना चाहते हैं।

  • स्टेटिक फ़ंक्शंस C या C ++ में बहुत समान व्यवहार करते हैं, जबकि नामहीन नाम स्पष्ट रूप से केवल C ++ हैं। नामहीन नाम भी इंडेंटेशन में अतिरिक्त स्तर जोड़ते हैं और मुझे यह पसंद नहीं है :)

इसलिए, मैं यह देखकर खुश हूं कि कार्यों के लिए स्थैतिक का उपयोग अब नहीं किया गया है


अनाम नाम स्थान में कार्य के लिए बाहरी लिंकेज होना चाहिए। वे सिर्फ उन्हें अद्वितीय बनाने के लिए तैयार हैं। केवल staticकीवर्ड वास्तव में किसी फ़ंक्शन के लिए स्थानीय लिंकेज लागू करता है। इसके अलावा, निश्चित रूप से केवल एक पागल हँसी वास्तव में नामस्थान के लिए इंडेंटेशन जोड़ देगा?
Roflcopter4

0

केवल आपके प्रश्न को पढ़ते हुए इस सुविधा के बारे में जानने के बाद, मैं केवल अटकलें लगा सकता हूं। ऐसा लगता है कि फ़ाइल-स्तर स्थिर वैरिएबल पर कई लाभ दिए गए हैं:

  • अज्ञात नाम स्थान एक दूसरे के भीतर घोंसले के शिकार हो सकते हैं, जिससे सुरक्षा के कई स्तर मिलते हैं, जिससे प्रतीक बच नहीं सकते।
  • कई अनाम नामस्थानों को एक ही स्रोत फ़ाइल में रखा जा सकता है, जिससे एक ही फ़ाइल के भीतर अलग-अलग स्थैतिक-स्तर स्कोप बन जाते हैं।

अगर किसी ने वास्तविक कोड में अनाम नामस्थान का उपयोग किया है, तो मुझे सीखने में दिलचस्पी होगी।


4
अच्छी अटकलें, लेकिन गलत। इन नामस्थानों का दायरा फ़ाइल-व्यापी है।
कोनराड रुडोल्फ

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

मैं गलत हो सकता हूं लेकिन, मुझे लगता है कि नहीं, यह फ़ाइल-वाइड नहीं है: यह अनाम नाम स्थान के बाद केवल कोड तक पहुंच योग्य है। यह एक सूक्ष्म बात है, और आमतौर पर, मैं एक स्रोत को कई अनाम नामस्थानों के साथ प्रदूषित नहीं करना चाहता ... फिर भी, इसके उपयोग हो सकते हैं।
पियरसबल

0

अंतर मंगली पहचानकर्ता का नाम है ( _ZN12_GLOBAL__N_11bEबनाम _ZL1b, जो वास्तव में मायने नहीं रखता है, लेकिन दोनों को प्रतीक तालिका में स्थानीय प्रतीकों में इकट्ठा किया जाता है ( .globalasm निर्देश का अभाव )।

#include<iostream>
namespace {
   int a = 3;
}

static int b = 4;
int c = 5;

int main (){
    std::cout << a << b << c;
}

        .data
        .align 4
        .type   _ZN12_GLOBAL__N_11aE, @object
        .size   _ZN12_GLOBAL__N_11aE, 4
_ZN12_GLOBAL__N_11aE:
        .long   3
        .align 4
        .type   _ZL1b, @object
        .size   _ZL1b, 4
_ZL1b:
        .long   4
        .globl  c
        .align 4
        .type   c, @object
        .size   c, 4
c:
        .long   5
        .text

एक नेस्टेड अनाम नामस्थान के लिए:

namespace {
   namespace {
       int a = 3;
    }
}

        .data
        .align 4
        .type   _ZN12_GLOBAL__N_112_GLOBAL__N_11aE, @object
        .size   _ZN12_GLOBAL__N_112_GLOBAL__N_11aE, 4
_ZN12_GLOBAL__N_112_GLOBAL__N_11aE:
        .long   3
        .align 4
        .type   _ZL1b, @object
        .size   _ZL1b, 4

अनुवाद इकाई में सभी प्रथम स्तर के अनाम नामस्थान एक दूसरे के साथ संयुक्त हैं, अनुवाद इकाई में सभी दूसरे स्तर के नामांकित अनाम नाम एक दूसरे के साथ संयुक्त हैं

एक अनाम नामस्थान में एक नेस्टेड (इनलाइन) नामस्थान भी हो सकता है

namespace {
   namespace A {
       int a = 3;
    }
}

        .data
        .align 4
        .type   _ZN12_GLOBAL__N_11A1aE, @object
        .size   _ZN12_GLOBAL__N_11A1aE, 4
_ZN12_GLOBAL__N_11A1aE:
        .long   3
        .align 4
        .type   _ZL1b, @object
        .size   _ZL1b, 4

which for the record demangles as:
        .data
        .align 4
        .type   (anonymous namespace)::A::a, @object
        .size   (anonymous namespace)::A::a, 4
(anonymous namespace)::A::a:
        .long   3
        .align 4
        .type   b, @object
        .size   b, 4

आपके पास अनाम इनलाइन नामस्थान भी हो सकते हैं, लेकिन जहां तक ​​मैं बता सकता हूं, inlineअनाम नाम स्थान पर 0 प्रभाव है

inline namespace {
   inline namespace {
       int a = 3;
    }
}

_ZL1b: _Zइसका मतलब यह एक पहचाना हुआ पहचानकर्ता है। Lइसका मतलब है कि यह एक स्थानीय प्रतीक है static1पहचानकर्ता की लंबाई bऔर उसके बाद पहचानकर्ता हैb

_ZN12_GLOBAL__N_11aE _Zइसका मतलब यह एक पहचाना हुआ पहचानकर्ता है। Nयह एक नाम स्थान है इसका मतलब है 12गुमनाम नाम स्थान नाम की लंबाई है _GLOBAL__N_1, तो गुमनाम नाम स्थान नाम _GLOBAL__N_1, तो 1पहचानकर्ता की लंबाई है a, aपहचानकर्ता है aऔरE पहचानकर्ता बंद कर देता है कि एक नाम स्थान में रहता है।

_ZN12_GLOBAL__N_11A1aE ऊपर के समान ही है, इसमें एक और नाम स्थान स्तर है 1A

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.