2011-10-31 11 views
13

क्या मैं निम्नलिखित कार्यक्रम के साथ एक परिभाषा नियम का उल्लंघन कर रहा हूं?अनाम नामस्थान और एक परिभाषा नियम

// foo.hpp 
#ifndef FOO_HPP_ 
#define FOO_HPP_ 

namespace { 
    inline int foo() { 
     return 1; 
    } 
} 

inline int bar() { 
    return foo(); 
} 
#endif 
//EOF 

और

// m1.cpp 

#include "foo.hpp" 

int m1() { 
    return bar(); 
} 

//EOF 

और

// m2.cpp 

#include "foo.hpp" 

int m2() { 
    return bar(); 
} 

//EOF 

और अंत में

// main.cpp 
#include <iostream> 

int m1(); 
int m2(); 

int main(int, const char* []) 
{ 
    int i = m1(); 
    int j = m2(); 

    std::cout << (i+j) << std::endl; 
    return 0; 
} 

// EOF 

ऊपर, नोट करें कि foo() एक गुमनाम नाम स्थान में परिभाषित किया गया है, इसलिए मुझे लगता है कि उम्मीद से प्रत्येक अनुवाद इकाई m1.cpp और m2.cpp का अपना संस्करण प्राप्त होगा, इसलिए ओडीआर का कोई उल्लंघन नहीं है। दूसरी तरफ, bar() सिर्फ एक सादा पुराना इनलाइन फ़ंक्शन है जो 2 अलग-अलग foo एस कॉल करने के लिए होता है। तो यह ओडीआर का उल्लंघन करता है, है ना?

अद्यतन: पहले मैं था foo की परिभाषा यह है कि अलग ढंग से foo.hpp शामिल करने से पहले मूल्य यह लौटे और m1 और m2 से प्रत्येक मैक्रो परिभाषित बदल में मैक्रोज़। (और उस पिछले उदाहरण के साथ, g++ एक बाइनरी उत्पन्न करेगा जो (i+j) आउटपुट के मुकाबले एक मूल्य के साथ आउटपुट करेगा।) लेकिन वास्तव में यह प्रोग्राम ओडीआर का उल्लंघन करता है भले ही foo() का शरीर समान है।

+5

मुझे लगता है कि यह स्पष्ट रूप से स्पष्ट करता है कि हेडर फाइलों में अनाम नामस्थान या स्थैतिक कार्यों का उपयोग क्यों परेशान करता है :) –

उत्तर

7

यह ओडीआर का उल्लंघन करता है। ,

डी के प्रत्येक परिभाषा

, इसी नाम, 3.4 के अनुसार ऊपर देखा एक इकाई डी की परिभाषा के भीतर परिभाषित करने का उल्लेख होगा, या: 3.2/5 जो निर्वासन इनलाइन कार्य (bar) के बारे में बात कर रही है देखें एक ही इकाई का उल्लेख करेगा ...

इस मामले bar में foo के दो विभिन्न संस्करणों को संदर्भित करता है, इस प्रकार नियम का उल्लंघन करने।

6

हां, bar() की यह परिभाषा एक परिभाषा नियम का उल्लंघन करती है। आप कई परिभाषाएं बना रहे हैं, जिनमें से प्रत्येक foo() नामक एक अलग फ़ंक्शन को कॉल करता है।

जैसा कि आप कहते हैं, यह उल्लंघन होगा यदि foo() के सभी संस्करण समान हैं, क्योंकि वे अभी भी अलग-अलग कार्य हैं।

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