क्या इनलाइन वर्चुअल फ़ंक्शंस वास्तव में एक गैर-भावना हैं?


172

मुझे यह प्रश्न तब मिला जब मुझे एक कोड समीक्षा टिप्पणी मिली जिसमें कहा गया था कि वर्चुअल फ़ंक्शन को इनलाइन नहीं होना चाहिए।

मैंने सोचा कि इनलाइन वर्चुअल फ़ंक्शंस उन परिदृश्यों में काम आ सकते हैं जहाँ फ़ंक्शंस को सीधे ऑब्जेक्ट्स पर बुलाया जाता है। लेकिन मेरे दिमाग में काउंटर-तर्क आया - कोई व्यक्ति वर्चुअल को परिभाषित करना चाहेगा और फिर कॉल करने के तरीकों के लिए वस्तुओं का उपयोग करेगा?

क्या इनलाइन वर्चुअल फ़ंक्शंस का उपयोग नहीं करना सबसे अच्छा है, क्योंकि वे लगभग कभी भी विस्तारित नहीं होते हैं?

कोड स्निपेट मैंने विश्लेषण के लिए इस्तेमाल किया:

class Temp
{
public:

    virtual ~Temp()
    {
    }
    virtual void myVirtualFunction() const
    {
        cout<<"Temp::myVirtualFunction"<<endl;
    }

};

class TempDerived : public Temp
{
public:

    void myVirtualFunction() const
    {
        cout<<"TempDerived::myVirtualFunction"<<endl;
    }

};

int main(void) 
{
    TempDerived aDerivedObj;
    //Compiler thinks it's safe to expand the virtual functions
    aDerivedObj.myVirtualFunction();

    //type of object Temp points to is always known;
    //does compiler still expand virtual functions?
    //I doubt compiler would be this much intelligent!
    Temp* pTemp = &aDerivedObj;
    pTemp->myVirtualFunction();

    return 0;
}

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

1
ऊपर आमतौर पर इनबिल्ड नहीं किया जाएगा, क्योंकि आप बेस क्लास की सहायता से वर्चुअल फंक्शन बुला रहे हैं। हालांकि यह केवल इस बात पर निर्भर करता है कि कंपाइलर कितना स्मार्ट है। यदि यह इंगित करने में सक्षम होगा कि pTemp->myVirtualFunction()इसे गैर-आभासी कॉल के रूप में हल किया जा सकता है, तो इसके पास इनलाइन हो सकती है। यह संदर्भित कॉल g ++ 3.4.2 द्वारा इनबिल्ट है: TempDerived & pTemp = aDerivedObj; pTemp.myVirtualFunction();आपका कोड नहीं है।
डॉच

1
वास्तव में एक बात gcc एक विशिष्ट प्रतीक के लिए व्यवहार्य प्रविष्टि की तुलना करती है और यदि यह मेल खाती है तो एक लूप में एक अंतर्निर्मित संस्करण का उपयोग करें। यह विशेष रूप से उपयोगी है यदि इनबिल्ड फ़ंक्शन खाली है और इस मामले में लूप को समाप्त किया जा सकता है।
साइमन रिक्टर

1
@doc आधुनिक संकलक कठिन समय पर यह निर्धारित करने का प्रयास करता है कि बिंदुओं के संभावित मान। किसी महत्वपूर्ण अनुकूलन स्तर पर इनलाइनिंग को रोकने के लिए बस एक पॉइंटर का उपयोग करना पर्याप्त नहीं है; जीसीसी भी अनुकूलन शून्य पर सरलीकरण करता है!
जिज्ञासु

जवाबों:


153

आभासी कार्यों को कभी-कभी इनलाइन किया जा सकता है। उत्कृष्ट C ++ faq का एक अंश :

"केवल एक इनलाइन वर्चुअल कॉल इनबिल्ट हो सकती है जब कंपाइलर ऑब्जेक्ट के" सटीक वर्ग "को जानता है जो वर्चुअल फ़ंक्शन कॉल का लक्ष्य है। यह केवल तभी हो सकता है जब कंपाइलर में पॉइंटर के बजाय एक वास्तविक ऑब्जेक्ट हो या किसी वस्तु का संदर्भ। यानी, एक स्थानीय वस्तु के साथ, एक वैश्विक / स्थिर वस्तु, या एक समग्र के अंदर पूरी तरह से निहित वस्तु। "


7
यह सच है, लेकिन यह याद रखने योग्य है कि कंपाइलर इनलाइन विनिर्देशक को अनदेखा करने के लिए स्वतंत्र है, भले ही कॉल को संकलन समय पर हल किया जा सकता है और इनलाइन हो सकता है।
शार्पट्यूट

6
जब मुझे लगता है कि अमानवीय स्थिति तब हो सकती है जब आप उदाहरण के लिए विधि को इस रूप में कहेंगे- Temp :: myVirtualFunction () - ऐसे इनवोकेशन वर्चुअल टेबल रिज़ॉल्यूशन को रोक देता है और फ़ंक्शन को समस्याओं के बिना इनलाइन किया जाना चाहिए - क्यों और यदि आप ' d इसे करना चाहते हैं एक और विषय :)
RnR

5
@RnR। यह 'यह->' होना आवश्यक नहीं है, केवल योग्य नाम का उपयोग करना पर्याप्त है। और यह व्यवहार विध्वंसक, निर्माणकर्ताओं और सामान्य रूप से असाइनमेंट ऑपरेटरों के लिए होता है (मेरा उत्तर देखें)।
रिचर्ड कॉर्डन

2
sharptooth - सच है, लेकिन AFAIK यह सभी इनलाइन फ़ंक्शन के बारे में सच है, न कि केवल वर्चुअल इनलाइन फ़ंक्शन।
कॉलन

2
void f (const base & lhs, const Base & rhs) {} ------ फ़ंक्शन के कार्यान्वयन में, आप कभी नहीं जानते हैं कि रनटाइम तक lhs और rhs क्या बताते हैं।
बैय्यांग हुआंग

72

C ++ 11 ने जोड़ा है final । यह स्वीकृत उत्तर को बदल देता है: वस्तु की सटीक कक्षा को जानना अब आवश्यक नहीं है, यह जानने के लिए पर्याप्त है कि वस्तु में कम से कम वर्ग प्रकार है जिसमें फ़ंक्शन अंतिम घोषित किया गया था:

class A { 
  virtual void foo();
};
class B : public A {
  inline virtual void foo() final { } 
};
class C : public B
{
};

void bar(B const& b) {
  A const& a = b; // Allowed, every B is an A.
  a.foo(); // Call to B::foo() can be inlined, even if b is actually a class C.
}

वीएस 2017 में इसे इनलाइन करने में सक्षम नहीं था।
योला

1
मुझे नहीं लगता कि यह इस तरह से काम करता है। एक सूचक / संदर्भ के माध्यम से फू () का आह्वान कभी भी इनलेट नहीं किया जा सकता है। कॉलिंग b.foo () को इनलाइनिंग की अनुमति देनी चाहिए। जब तक आप यह सुझाव नहीं दे रहे हैं कि संकलक पहले से ही जानता है कि यह एक प्रकार बी है क्योंकि यह पिछली पंक्ति से अवगत है। लेकिन यह विशिष्ट उपयोग नहीं है।
जेफरी फॉस्ट

उदाहरण के लिए, बार और आधार के लिए जनरेट किए गए कोड की तुलना यहां करें: godbolt.org/g/xy3rNh
Jeffrey Faust

@JeffreyFaust कोई कारण नहीं है कि जानकारी को प्रचारित नहीं किया जाना चाहिए, क्या वहाँ है? और iccउस लिंक के अनुसार, ऐसा लगता है।
एलेक्सी रोमानोव

@AlexeyRomanov कम्पाइलर्स को मानक से परे अनुकूलन करने की स्वतंत्रता है, और निश्चित रूप से करते हैं! ऊपर जैसे सरल मामलों के लिए, कंपाइलर प्रकार जान सकता है और इस अनुकूलन को कर सकता है। चीजें शायद ही कभी इस सरल हैं, और यह संकलन के समय में पॉलीमोर्फिक चर के वास्तविक प्रकार को निर्धारित करने में सक्षम होने के लिए विशिष्ट नहीं है। मुझे लगता है कि ओपी को general सामान्य ’की परवाह है और इन विशेष मामलों की नहीं।
जेफरी फॉस्ट

37

वर्चुअल फ़ंक्शंस की एक श्रेणी है जहां यह अभी भी उन्हें इनलाइन करने के लिए समझ में आता है। निम्नलिखित मामले पर विचार करें:

class Base {
public:
  inline virtual ~Base () { }
};

class Derived1 : public Base {
  inline virtual ~Derived1 () { } // Implicitly calls Base::~Base ();
};

class Derived2 : public Derived1 {
  inline virtual ~Derived2 () { } // Implicitly calls Derived1::~Derived1 ();
};

void foo (Base * base) {
  delete base;             // Virtual call
}

'आधार' को हटाने के लिए कॉल, सही व्युत्पन्न वर्ग विध्वंसक को कॉल करने के लिए एक आभासी कॉल करेगा, यह कॉल इनबिल्ड नहीं है। हालाँकि, क्योंकि प्रत्येक विध्वंसक इसे अभिभावक विध्वंसक कहता है (जो इन मामलों में रिक्त हैं), संकलक इनलाइन कर सकता है उन कॉल , क्योंकि वे आधार वर्ग के कार्यों को वस्तुतः नहीं कहते हैं।

बेस क्लास कंस्ट्रक्टर्स या फ़ंक्शंस के किसी भी सेट के लिए एक ही सिद्धांत मौजूद है, जहाँ व्युत्पन्न कार्यान्वयन बेस क्लास कार्यान्वयन को भी कहते हैं।


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

14

मैंने ऐसे कंपाइलर देखे हैं जो किसी भी गैर-तालिका का उत्सर्जन नहीं करते हैं यदि कोई भी गैर-इनलाइन फ़ंक्शन मौजूद नहीं है (और हेडर के बजाय एक कार्यान्वयन फ़ाइल में परिभाषित किया गया है)। वे त्रुटियों missing vtable-for-class-Aया जैसे कुछ भी फेंक देंगे , और आप नरक के रूप में भ्रमित होंगे, जैसा कि मैं था।

वास्तव में, यह मानक के अनुरूप नहीं है, लेकिन ऐसा होता है इसलिए कम से कम एक वर्चुअल फ़ंक्शन को हेडर में नहीं (यदि केवल वर्चुअल डिस्ट्रक्टर) डाल दिया जाए, ताकि कंपाइलर उस स्थान पर क्लास के लिए एक वाइबेट का उत्सर्जन कर सके। मुझे पता है कि यह कुछ संस्करणों के साथ होता हैgcc

जैसा कि किसी ने उल्लेख किया है, इनलाइन वर्चुअल फ़ंक्शंस कभी-कभी एक लाभ हो सकता है , लेकिन निश्चित रूप से सबसे अधिक बार आप इसका उपयोग करेंगे जब आप ऑब्जेक्ट के गतिशील प्रकार को नहीं जानते हैं, क्योंकि यह virtualपहली जगह के लिए पूरा कारण था ।

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


11

ठीक है, वास्तव में आभासी कार्यों को हमेशा इनलेट किया जा सकता है , जब तक कि वे सांख्यिकीय रूप से एक साथ जुड़े हुए हैं: मान लें कि हमारे पास Base एक आभासी फ़ंक्शन Fऔर व्युत्पन्न वर्ग के साथ एक सार वर्ग है Derived1और Derived2:

class Base {
  virtual void F() = 0;
};

class Derived1 : public Base {
  virtual void F();
};

class Derived2 : public Base {
  virtual void F();
};

एक काल्पनिक कॉल b->F();( bप्रकार के साथ Base*) स्पष्ट रूप से आभासी है। लेकिन आप (या संकलक ...) इसे फिर से लिख सकते हैं जैसे (मान लीजिए कि typeofयह एक समान typeidफ़ंक्शन है जो एक मान लौटाता है जो कि एक में इस्तेमाल किया जा सकता है switch)

switch (typeof(b)) {
  case Derived1: b->Derived1::F(); break; // static, inlineable call
  case Derived2: b->Derived2::F(); break; // static, inlineable call
  case Base:     assert(!"pure virtual function call!");
  default:       b->F(); break; // virtual call (dyn-loaded code)
}

जबकि हमें अभी भी आरटीटीआई की आवश्यकता है typeof, कॉल को प्रभावी रूप से इनलाइन किया जा सकता है, मूल रूप से, निर्देश स्ट्रीम के अंदर वाइबेट को एम्बेड करना और सभी शामिल वर्गों के लिए कॉल की विशेषज्ञता है। यह केवल कुछ वर्गों (जैसे, बस Derived1) को विशेषज्ञता देकर सामान्यीकृत किया जा सकता है :

switch (typeof(b)) {
  case Derived1: b->Derived1::F(); break; // hot path
  default:       b->F(); break; // default virtual call, cold path
}

क्या वे कोई संकलक हैं जो ऐसा करते हैं? या यह सिर्फ अटकलबाजी है? क्षमा करें यदि मैं अत्यधिक उलझन में हूं, लेकिन ऊपर दिए गए विवरण में आपका स्वर कुछ इस तरह का है - "वे पूरी तरह से ऐसा कर सकते हैं!", जो "कुछ कंपाइलर ऐसा करते हैं" से अलग है।
एलेक्स मेइबर्ग

हाँ, ग्रेगल पॉलीमोर्फिक इनलाइनिंग करता है (सलॉन्ग के माध्यम से एलएलवीएम बिटकोड के लिए भी)
सीएएफएक्सएक्स

4

एक आभासी विधि इनलाइन को चिह्नित करना, दो मामलों के बाद आभासी कार्यों के अनुकूलन में मदद करता है:


3

इनलाइन वास्तव में कुछ भी नहीं करता है - यह एक संकेत है। संकलक इसे अनदेखा कर सकता है या यह इनलाइन के बिना कॉल इवेंट को इनलाइन कर सकता है यदि यह कार्यान्वयन को देखता है और इस विचार को पसंद करता है। यदि कोड स्पष्टता दांव पर है तो इनलाइन को हटा दिया जाना चाहिए।


2
केवल TUs पर काम करने वाले कंपाइलरों के लिए, वे केवल अंतर्निहित कार्यों को ही इनलाइन कर सकते हैं, जिनके लिए उनकी परिभाषा है। एक फ़ंक्शन को केवल एकाधिक टीयू में परिभाषित किया जा सकता है यदि आप इसे इनलाइन बनाते हैं। 'इनलाइन' एक संकेत से अधिक है और इसमें जी ++ / मेकफाइल बिल्ड के लिए नाटकीय प्रदर्शन में सुधार हो सकता है।
रिचर्ड कॉर्डन

3

इनलाइन घोषित वर्चुअल फ़ंक्शंस तब इनलाइन किए जाते हैं जब ऑब्जेक्ट्स के माध्यम से कॉल किए जाते हैं और जब पॉइंटर या रेफ़रेंस के माध्यम से कॉल किए जाते हैं तो उन्हें अनदेखा कर दिया जाता है।


1

आधुनिक संकलक के साथ, यह उन्हें प्रभावित करने में कोई नुकसान नहीं करेगा। कुछ प्राचीन संकलक / लिंकर कोम्बो ने कई vtables बनाए हो सकते हैं, लेकिन मुझे नहीं लगता कि यह अब कोई मुद्दा है।


1

एक कंपाइलर केवल एक फ़ंक्शन को इनलाइन कर सकता है जब संकलन समय पर कॉल को स्पष्ट रूप से हल किया जा सकता है।

वर्चुअल फ़ंक्शंस, हालांकि रनटाइम पर हल किए जाते हैं, और इसलिए कंपाइलर कॉल को इनलाइन नहीं कर सकता है, क्योंकि कंपाइल टाइप पर डायनेमिक टाइप (और इसलिए फंक्शन इम्प्लीमेंटेशन जिसे कॉल किया जाता है) निर्धारित नहीं किया जा सकता है।


1
जब आप बेस क्लास मेथड को उसी या व्युत्पन्न वर्ग से कॉल करते हैं तो कॉल असंदिग्ध और गैर-आभासी है
शार्पटूट

1
@ साभार: लेकिन फिर यह एक गैर-आभासी इनलाइन विधि होगी। संकलक इनलाइन फ़ंक्शंस कर सकता है जो आप इसे नहीं पूछते हैं, और यह संभवतः बेहतर जानता है कि कब इनलाइन है या नहीं। तय करने दो।
डेविड रॉड्रिग्ज - dribeas

1
@ ड्रिबेसा: हाँ, यह वही है जो मैं बात कर रहा हूँ। मैंने केवल इस कथन पर आपत्ति जताई है कि वर्चुअल फ़िक्शन रनटाइम पर हल हो जाते हैं - यह केवल तभी सच होता है जब कॉल वस्तुतः किया जाता है, सटीक क्लास के लिए नहीं।
शार्प फुट

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

1

उन मामलों में जहां फ़ंक्शन कॉल असंदिग्ध है और फ़ंक्शन इनलाइनिंग के लिए उपयुक्त उम्मीदवार है, कंपाइलर वैसे भी कोड को इनलाइन करने के लिए पर्याप्त स्मार्ट है।

बाकी समय "इनलाइन वर्चुअल" एक बकवास है, और वास्तव में कुछ संकलक उस कोड को संकलित नहीं करेंगे।


जी ++ का कौन सा संस्करण इनलाइन वर्चुअल का संकलन नहीं करेगा?
थॉमस एल होलाडे 13

हम्म। ४.१.१ मैं यहाँ अब खुश प्रतीत होता है। मैंने पहली बार 4.0.x का उपयोग करके इस कोडबेस के साथ समस्याओं का सामना किया। लगता है कि मेरी जानकारी पुरानी है, संपादित की गई है।
मूनशैडो

0

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


0

वास्तव में कुछ मामलों में एक आभासी अंतिम ओवरराइड में "इनलाइन" जोड़ने से आपका कोड संकलित नहीं हो सकता है इसलिए कभी-कभी अंतर होता है (कम से कम VS2017s संकलक के तहत)!

वास्तव में मैं VS2017 में वर्चुअल इनलाइन अंतिम ओवरराइड फ़ंक्शन कर रहा था, संकलन और लिंक करने के लिए c ++ 17 मानक जोड़ रहा था और किसी कारण से यह विफल हो गया जब मैं दो परियोजनाओं का उपयोग कर रहा हूं।

मेरे पास एक परीक्षण परियोजना और एक कार्यान्वयन डीएलएल था जिसका मैं इकाई परीक्षण कर रहा हूं। परीक्षण परियोजना में मुझे एक "linker_includes.cpp" फ़ाइल मिल रही है, जो आवश्यक है * # .cpp फ़ाइलों को अन्य प्रोजेक्ट से #include करें। मुझे पता है ... मुझे पता है कि मैं DLL से ऑब्जेक्ट फ़ाइलों का उपयोग करने के लिए msbuild सेट कर सकता हूं, लेकिन कृपया ध्यान रखें कि यह एक Microsoft विशिष्ट समाधान है, जबकि cpp फाइलें बिल्ड-सिस्टम से असंबंधित है और संस्करण के लिए बहुत आसान है xml फ़ाइलों और प्रोजेक्ट सेटिंग्स की तुलना में एक cpp फ़ाइल और ऐसी ...

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

मुझे लगता है कि यह संकलक में किसी प्रकार का बग है। मुझे कोई पता नहीं है अगर यह VS2020 के साथ संकलित कंपाइलर में मौजूद है, क्योंकि मैं एक पुराने संस्करण का उपयोग कर रहा हूं क्योंकि कुछ एसडीके केवल उसी के साथ ठीक से काम करता है :-(

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

पुनश्च: मैं जिस कोड पर काम कर रहा हूं वह कंप्यूटर ग्राफिक्स से संबंधित है, इसलिए मैं इनलाइनिंग पसंद करता हूं और यही कारण है कि मैंने अंतिम और इनलाइन दोनों का उपयोग किया। मैं अंतिम विनिर्देशक को उम्मीद करता हूं कि रिलीज बिल्ड काफी स्मार्ट है, डीएलएल का निर्माण करने के लिए इसे सीधे मेरे बिना भी हेटिंग के साथ ...

PS (लिनक्स): मुझे उम्मीद है कि gcc या क्लैंग में वैसा नहीं होगा जैसा कि मैं नियमित रूप से इस तरह की चीजों को करने के लिए करता था। मुझे यकीन नहीं है कि यह मुद्दा कहां से आता है ... मैं लिनक्स पर या कुछ gcc के साथ कम से कम c ++ करना पसंद करता हूं, लेकिन कभी-कभी परियोजना आवश्यकताओं में भिन्न होती है।

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