2015-10-28 90 views
2

我遇到了一個奇怪的問題,那種破壞我對編譯單元封裝的理解。在不同的編譯單元中編譯具有不同編譯標誌的相同頭文件

簡而言之,我有一個從頭部獲得的公共內聯函數。
我將其包含到2個不同的.cpp文件中,使用不同的#define宏。
但我最終在bot編譯單元中獲得了相同的實現。

COMMON.H:

#include <iostream> 

inline void printA() 
{ 
#ifdef YES 
    std::cout << " yes" << std::endl; 
#else 
    std::cout << " no" << std::endl; 
#endif 
} 

File1.h:

void print1(); 

File1.cpp:

#define YES 
#include "Common.h" 
#include "File1.h" 

void print1() 
{ 
    printA(); 
} 

File2.h:

void print2(); 

File2.cpp

#include "Common.h" 
#include "File2.h" 
void print2() 
{ 
    printA(); 
} 

main.cpp中:

#include "File1.h" 
#include "File2.h" 

int main(int argc, char* argv[]) 
{ 

    print1(); 
    print2(); 

    return 0; 
} 

輸出這個例子是:

yes 
yes 

我希望它是:

yes 
no 

那麼,爲什麼是相同的實現在兩個編譯單元中採用?
通用功能甚至內聯....

如何獲得我的「預期」結果?

而且,爲什麼選擇「是」實現?只是一個彙編命令的問題?

順便說一句,我得到了同樣的結果在GCC 4.8和VS2012

+0

在file2.cpp中,你包含'file.h',我沒有看到。 – Brahim

+0

請**編輯您的帖子**的內容* Common.h *。 –

+0

我仍然看到file.hpp包含file.hpp – Brahim

回答

3

標準(這裏N4527)說,在3.2的一個定義規則/6

可以有一個以上的定義(7.1.2),類模板(子句14),非靜態函數模板(14.5.6),靜態數據成員 的一個類型(第9章),枚舉類型(7.2),內聯函數 類模板(14.5.1.3),類模板的成員函數(14.5.1.1)或模板專用 某些模板參數未在程序中指定(14.7,14.5.5),前提是每個定義 出現在不同的翻譯單元中,並且提供的定義滿足以下要求。鑑於 這樣一個實體命名D定義在多個翻譯單位,然後 (6。1)

- D的每個定義應包含相同的令牌序列;和

...

如果d的定義滿足所有這些要求, 則行爲好像有D的單一的定義。如果d的定義不滿足這些 要求,那麼行爲是不確定的。

因此,將「yes」替換爲「no」會違反ODR,導致未定義的行爲。

對於獲得「是」的結果,我可以猜測編譯器隨機選取一個函數,因爲它們的必須與相同。

另一方面,如果您製作了功能static,則每個翻譯單元中都會有不同的本地功能。

相關問題