2012-06-26 21 views
9

मिनिमल कोड:क्या यह एक अनिर्धारित व्यवहार है जिसमें इनलाइन फ़ंक्शन की अलग-अलग परिभाषाएं हैं?

// --------inline.h-------- 
struct X { 
    static inline void foo(); 
}; 
#ifdef YES 
inline void X::foo() { cout << "YES\n"; } 
#else 
inline void X::foo() { cout << "NO\n"; } 
#endif 

// --------file1.cpp-------- 
#define YES // <---- 
#include"inline.h" 
void fun1() 
{ 
    X::foo(); 
} 

// --------file2.cpp-------- 
#include"inline.h" 
void fun2() 
{ 
    X::foo(); 
} 

अगर हम कहते हैं fun1() और fun2(), तो वे YES और NO क्रमशः प्रिंट होगा, जिसका अर्थ है कि वे एक ही X::foo() के विभिन्न समारोह निकायों बात कर रहे हैं।

इसके बावजूद इसे कोड किया जाना चाहिए या नहीं, मेरा प्रश्न है:
क्या यह एक अच्छी तरह परिभाषित या अपरिभाषित व्यवहार है?

+0

यदि आप दो अलग-अलग फ़ाइलों में दो अलग-अलग फ़ंक्शंस (क्लास सदस्य नहीं) चाहते हैं लेकिन एक ही नाम के साथ, तो आप उन्हें 'स्थिर' कीवर्ड (या अज्ञात नामस्थान) से अलग कर सकते हैं। Stat2 के रूप में file2.cpp में फ़ंक्शन को चिह्नित करना मतलब है कि लिंक करने के दौरान कोई अन्य .cpp फ़ाइल इसे देख नहीं सकती है। यह बहुत बड़े कार्यक्रमों के लिए उपयोगी है जहां आप हमेशा यह सुनिश्चित नहीं कर सकते कि पहले से ही कार्यों द्वारा आम नाम क्या उठाए गए हैं। – Crashworks

+0

आपको वास्तव में इनलाइन में hline.h और # परिभाषित हैक की आवश्यकता नहीं है; बस फ़ाइल 1.cpp में एक तरफ "शून्य एक्स :: foo()" (इनलाइन के साथ या बिना) परिभाषित करें, और दूसरा file2.cpp में, और आपके पास एक ही व्यवहार होगा। – abarnert

+0

@abarnert: 'इनलाइन' परिणामों को एक परिभाषा नियम के एक अलग उल्लंघन में छोड़ना। गैर-इनलाइन फ़ंक्शंस 3.2 अनुच्छेद 3, 3.2 अनुच्छेद 5 द्वारा इनलाइन फ़ंक्शंस द्वारा कवर किए गए हैं। कई (अधिकांश?) लिंकर्स गैर-इनलाइन उल्लंघनों को पकड़ते हैं। मेरा कम से कम इनलाइन उल्लंघनों को पकड़ नहीं लेता है। –

उत्तर

13

हां यह अनिर्धारित व्यवहार है।

संदर्भ:

सी ++ 03 मानक:

7.1.2 समारोह विनिर्देशक [dcl.fct.spec]
पैरा 4:

एक इनलाइन फ़ंक्शन को प्रत्येक अनुवाद इकाई में परिभाषित किया जाएगा जिसमें इसका उपयोग किया जाता है और वास्तव में होगा प्रत्येक मामले में एक ही परिभाषा (3.2)। [नोट: अनुवाद इकाई में इसकी परिभाषा प्रकट होने से पहले इनलाइन फ़ंक्शन पर कॉल का सामना किया जा सकता है। ] यदि बाहरी अनुवाद के साथ एक फ़ंक्शन को एक अनुवाद इकाई में इनलाइन घोषित किया जाता है, तो इसे सभी अनुवाद इकाइयों में इनलाइन घोषित किया जाएगा जिसमें यह प्रतीत होता है; कोई निदान की आवश्यकता नहीं है। बाहरी लिंकेज के साथ इनलाइन फ़ंक्शन में सभी अनुवाद इकाइयों में एक ही पता होगा। एक बाहरी इनलाइन फ़ंक्शन में एक स्थिर स्थानीय चर हमेशा एक ही ऑब्जेक्ट को संदर्भित करता है। एक बाहरी इनलाइन फ़ंक्शन में शाब्दिक एक स्ट्रिंग अलग-अलग अनुवाद इकाइयों में एक ही वस्तु है।

नोट:

3,2 एक परिभाषा नियम [basic.def.odr]
पैरा 1:

कोई 3.2 एक परिभाषा नियम, जिसमें कहा गया है को संदर्भित करता है अनुवाद इकाई में किसी भी चर, फ़ंक्शन, कक्षा प्रकार, गणना प्रकार या टेम्पलेट की एक से अधिक परिभाषाएं होंगी।

+0

+1। साथ ही, ध्यान दें कि इनलाइन केवल एक संकेत है (हालांकि यह इस मामले में आपको चेतावनी देने के लिए एक अच्छा अवसर खोने में संकलक और/या लिंकर को भी मूर्ख बना सकता है)। – abarnert

+3

@abarnert: 'inline' एक संकेत से कहीं अधिक है। फ़ंक्शन बॉडी के साथ फ़ंक्शन कॉल को प्रतिस्थापित किया जाता है, यह कंपाइलर के विवेकानुसार होता है लेकिन एक बार जब आप 'इनलाइन' कंपाइलर का उपयोग करते हैं ** ** ** निश्चित नियमों का पालन करना चाहिए एक परिभाषा नियम। –

+0

हां, लेकिन नियमों का प्रभावी ढंग से क्या कहना है कि इनलाइन का उपयोग करने से आपको ओडीआर के आसपास नहीं मिल सकता है, यह समझने के लिए कि आप एक ही परिभाषा को दोहरा सकते हैं। – abarnert

7

अपरिभाषित। आप ओडीआर का उल्लंघन कर रहे हैं।

4

अगर हम fun1() और fun2() फोन है, तो वे हाँ प्रिंट होगा और कोई क्रमशः, जिसका अर्थ है कि वे एक ही एक्स के विभिन्न समारोह निकायों :: foo बात कर रहे हैं()।

क्या आपने इसे आजमाया? विभिन्न अनुकूलन स्तर के साथ?

मुझे अनुकूलन स्तर और ऑर्डर किए गए ऑब्जेक्ट को लिंकर को प्रस्तुत किए जाने वाले ऑर्डर के आधार पर हाँ और नहीं, हाँ और हाँ, या NO और NO मिलता है।

कहने की जरूरत नहीं है, यह अपरिभाषित व्यवहार है।

+0

+1। मुझे यह नहीं पता है। मैं '-O4' के साथ संकलित। – iammilind

+1

@ एएलएस: अपरिभाषित व्यवहार के जंगली रूप से भिन्न व्यवहार का निरीक्षण करना सबूत (यदि पर्याप्त प्रमाण नहीं है) है। यह विपरीत है कि खतरनाक है (लगातार व्यवहार का निरीक्षण करना अच्छा सबूत नहीं है कि यह अपरिभाषित व्यवहार नहीं है)। – abarnert

+3

@ एएलएस: मुझे एहसास हुआ कि व्यवहार व्यवहार प्रमाण नहीं है। मुझे पता था कि यह पहले से ही यूबी था। मैंने सोचा कि यह देखने में दिलचस्प लगेगा कि क्या उत्पादित किया गया था, और यह देखने के लिए कि इसके साथ खिलौना कैसे अलग-अलग परिणाम उत्पन्न करने के लिए है। –