सी ++ - वैश्विक स्थैतिक वस्तु और स्थानीय स्थैतिक वस्तु का कन्स्ट्रक्टर कॉल अलग है?

There is a same question here : When exactly is constructor of static local object called?

लेकिन यह केवल स्थानीय स्थैतिक वस्तु पर उल्लेख करता है, इसलिए मैं वैश्विक स्थैतिक वस्तु के लिए एक और मामला जोड़ना चाहता हूं।

मान लें कि हमारे पास 2 उदाहरण कोड हैं:

परीक्षा 1. स्थानीय स्थैतिक ==========

class Mix {
Mix() { //the ctor code }
};

Mix& globalFunction()
{
static Mix gMix;//when its ctor execute ?
return gMix;
}

परीक्षा 2. वैश्विक स्थैतिक ==========

class Mix {
Mix() { //the ctor code }
static MyClass MReen;//when its ctor execute ?
};

//initialization static var
MyClass Mix::MReen = 0 ;
  • जब उपरोक्त 2 स्थिर वस्तुओं का बिल्कुल 'कन्स्ट्रक्टर कोड' निष्पादित किया जाता है?
  • यह g ++ (लिनक्स पर चलने) और वीसी ++ कंपाइलर के बीच अलग-अलग कैसे है?

धन्यवाद

0
धन्यवाद, मुझे MyClass की कमी थी। अपडेट किया गया।
जोड़ा लेखक Thang Le, स्रोत
Mix :: MReen = 0 एक असाइनमेंट है, प्रारंभिक नहीं है, और इसकी वैश्विक अनुमति पर अनुमति नहीं है। इसे प्रारंभ करने के लिए MyClass को पूर्ववत करें, हालांकि 0 को प्रारंभ करना अनावश्यक है।
जोड़ा लेखक uk4321, स्रोत
उत्तर यहां है: stackoverflow.com/questions/246564/…
जोड़ा लेखक Andrey Mishchenko, स्रोत

2 उत्तर

मैं एडम पियर्स से यहां , और दो और मामलों को जोड़ा: कक्षा और पीओडी प्रकार में स्थिर चर। मेरा कंपाइलर विंडोज ओएस (मिनजीडब्लू -32) में जी ++ 4.8.1 है। परिणाम क्लास में स्थैतिक चर वैश्विक चर के साथ समान व्यवहार किया जाता है। मुख्य कार्य में प्रवेश करने से पहले इसके कन्स्ट्रक्टर को बुलाया जाएगा।

  • Conclusion (for g++, Windows environment):

    1. Global variable and static member in class: constructor is called before enter main function (1).
    2. Local static variable: constructor is only called when execution reaches its declaration at first time.
    3. If Local static variable is POD type, then it is also initialized before enter main function (1). Example for POD type: static int number = 10;

(1): The correct state should be: "before any function from the same translation unit is called". However, for simple, as in example below, then it is main function.

include < iostream>

#include < string>

using namespace std;

class test
{
public:
   test(const char *name)
            : _name(name)
    {
            cout << _name << " created" << endl;
    }

    ~test()
    {
            cout << _name << " destroyed" << endl;
    }

    string _name;
    static test t;//static member
 };
test test::t("static in class");

test t("global variable");

void f()
{
    static  test t("static variable");
    static int num = 10 ;//POD type, init before enter main function

    test t2("Local variable");
    cout << "Function executed" << endl;
}

int main()
{
    test t("local to main");
    cout << "Program start" << endl;
    f();
    cout << "Program end" << endl;
    return 0;
 }

परिणाम:

static in class created
global variable created
local to main created
Program start
static variable created
Local variable created
Function executed
Local variable destroyed
Program end
local to main destroyed
static variable destroyed
global variable destroyed
static in class destroyed

किसी ने लिनक्स एनवी में परीक्षण किया?

0
जोड़ा
  1. A local static variable, declared in an function, is initialised before the first call to the function. You can read more about this aspects of C++ standard here https://stackoverflow.com/a/58804/747050.
  2. Global static variable is initialised before main(), but if you have several files the order is not garantied even within one compiler. Here is related answers: http://www.parashift.com/c++-faq/static-init-order.html , Can the compiler deal with the initialization order of static variables correctly if there is dependency?

    p.s. You can guarantee the order for const static with one trick:

    int YourClass::YourStaticVar()
    {
        static const int value = 0;
        return value;
    }
    
0
जोड़ा
@ klm123: यह मानते हुए कि dll में एक स्थानीय स्थिर चर घोषित किया गया है कि मेरा एप्लिकेशन लिंक कर रहा है। मेरे आवेदन में, यह इस स्थैतिक चर के फ़ंक्शन होल्डिंग घोषणा के संदर्भ में कभी भी संदर्भ नहीं देता है। तो, इस स्थानीय स्थैतिक चर के ctor कभी नहीं कहा जाएगा? यदि वह है, तो यह काफी गंभीर है क्योंकि शायद इस चर के सीटीओ को हार्डवेयर शुरू करने के कुछ कारणों से बुलाया जाना चाहिए ...
जोड़ा लेखक Thang Le, स्रोत
@ एंड्रीटी: आपसे सहमत हैं। यहां तक ​​कि यह वैश्विक वस्तु है तो मुख्य से पहले प्रारंभ करना आवश्यक नहीं है।
जोड़ा लेखक Thang Le, स्रोत
@ klm123: उद्धृत लिंक से, एडम पिएर्स का उदाहरण देखें। यह देखने के लिए काफी स्पष्ट है कि कन्स्ट्रक्टर को केवल कार्य करने के लिए पहली कॉल में बुलाया जाता है :))। मैं पुष्टि करने के लिए फिर से एक परीक्षण लिखूंगा। यदि आवश्यक हो तो आप एडम पिएर्स के उदाहरण कोड में टिप्पणी कर सकते हैं। क्योंकि यह चर्चा बहुत लंबी है, इसलिए हमें यहां रुकना चाहिए।
जोड़ा लेखक Thang Le, स्रोत
@ klm123: तो, पहली बार निष्पादन इसकी घोषणा तक पहुंचने से पहले निर्माता को बुलाया जाएगा? आइटम 4 से, मुझे लगता है कि यह नियम केवल पीओडी प्रकार के लिए लागू है। काफी भ्रमित, कुछ लोगों ने बताया कि समारोह में पहली कॉल से पहले कन्स्ट्रक्टर को निष्पादित किया गया है। किसी को लगता है कि इसे केवल कार्य करने के लिए पहली कॉल में बुलाया जाता है। इस मामले की जांच करने के लिए एक विधि की आवश्यकता है।
जोड़ा लेखक Thang Le, स्रोत
@ klm123: कृपया अपना पहला उत्तर दोबारा पुष्टि करें: 1 फ़ंक्शन में घोषित एक स्थानीय स्थैतिक चर, फ़ंक्शन पर पहली कॉल से पहले प्रारंभ किया गया है। आप http://stackoverflow.com/a/58804/747050 पर C ++ मानक के इन पहलुओं के बारे में अधिक पढ़ सकते हैं। । यह सही है ?। चूंकि आपका लिंक गैर-स्थानीय ऑब्जेक्ट्स के बारे में बात करता है
जोड़ा लेखक Thang Le, स्रोत
@ klm123, हाँ, यह करने का एक तरीका हो सकता है। धन्यवाद
जोड़ा लेखक Thang Le, स्रोत
हाय, कुछ लोगों ने मुझे बताया कि स्थानीय स्थैतिक वस्तु का कन्स्ट्रक्टर (यहां मिक्स है) केवल एक बार फ़ंक्शन globalFunction को पहली बार बुलाया जाता है। लेकिन कुछ अन्य विचारों ने बताया कि निर्माता को मुख्य से पहले बुलाया जाता है, यह डीएल लोडिंग समय के दौरान होना चाहिए। तो, सही क्या है?
जोड़ा लेखक Thang Le, स्रोत
@EJP, आप एक अधिकार है। धन्यवाद।
जोड़ा लेखक klm123, स्रोत
@ थांगले, कन्स्ट्रक्टर को तब कहा जाता है जब कक्षा का एक उदाहरण घोषित किया जाता है। यदि आप एक उदाहरण स्थानीय बनाते हैं तो इसे मुख्य() से पहले नहीं कहा जाएगा।
जोड़ा लेखक klm123, स्रोत
@ थांगले, इसे कभी नहीं कहा जा सकता है। यह हार्डवेयर को प्रारंभ करने के लिए ctor को कॉल करने की आवश्यकता है, तो शायद आपको हार्डवेयर का उपयोग करने से पहले फ़ंक्शन को कॉल करने या ऑब्जेक्ट इंस्टेंस को परिभाषित करने की आवश्यकता है?
जोड़ा लेखक klm123, स्रोत
@EJP, इस मामले में ग्लोबल फंक्शन() कॉल।
जोड़ा लेखक klm123, स्रोत
@ थांगले, क्या आपने उद्धरण पर आइटम 4 पढ़ा है, जिसे अर्कडी ने दिया था? "सभी स्थानीय वस्तुओं का शून्य-प्रारंभिकरण (dcl.init) ..."
जोड़ा लेखक klm123, स्रोत
@ थांगले, मैं पहले ही उलझन में हूं। यह चर्चा बहुत लंबी है। बेहतर quesion बनाएँ जहां विवरण में स्थिति का वर्णन करें।
जोड़ा लेखक klm123, स्रोत
तब मुझे विश्वास है कि आप गलत हैं। फ़ंक्शन कहने से पहले इसे निष्पादित करने की गारंटी है, लेकिन 'पहले कॉल पर' जरूरी नहीं है।
जोड़ा लेखक EJP, स्रोत
आपकी पहली वाक्य का क्या अर्थ है? क्या फंक्शन कॉल?
जोड़ा लेखक EJP, स्रोत
जवाब सटीक नहीं है। जब स्थानीय नियंत्रण पहली बार अपनी परिभाषा से गुजरता है ("फ़ंक्शन पर पहली कॉल से पहले नहीं) तो स्थानीय स्थैतिक वस्तु को निष्क्रिय किया जाता है। यदि नियंत्रण निश्चित रूप से कभी खत्म नहीं होता है, तो ऑब्जेक्ट कभी शुरू नहीं होता है, भले ही युक्त फ़ंक्शन को कई बार बुलाया जाता है। एक वैश्विक स्थैतिक वस्तु को मुख्य से पहले अनिवार्य रूप से initailized नहीं है। भाषा कहती है कि उसी अनुवाद इकाई से किसी भी फ़ंक्शन को कॉल करने से पहले इसे प्रारंभ किया जाता है, जो main निष्पादन शुरू होने के बाद आसानी से हो सकता है।
जोड़ा लेखक AnT, स्रोत
कई संकलक लिंकिंग के दौरान ऑब्जेक्ट फ़ाइलों के क्रम द्वारा स्थिर वस्तुओं का निर्माण आदेश देते हैं। यदि ऐसा है, तो संकलक के लिए दस्तावेज़ों में इसका उल्लेख किया जाना चाहिए।
जोड़ा लेखक Kirill Kobelev, स्रोत