2011-10-12 24 views
3

有沒有什麼方法可以用MSVC模擬inline namespaceMSVC的內聯命名空間模擬(10.0/11.0)

LLVM的libc中++使用它來創建一個隱藏的版本命名空間,像這樣:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE { 
#define _LIBCPP_END_NAMESPACE_STD } } 
#define _VSTD std::_LIBCPP_NAMESPACE 
namespace std { 
    inline namespace _LIBCPP_NAMESPACE { 
    } 
} 

並模擬它在GCC像這樣:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE { 
#define _LIBCPP_END_NAMESPACE_STD } } 
#define _VSTD std::_LIBCPP_NAMESPACE 

namespace std { 
namespace _LIBCPP_NAMESPACE { 
} 
using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); 
} 

現在的問題是,我該如何實現相同的與MSVC?如果這是不可能的,我會很高興與省去了版本(現在)的解決方案,這是我的猜測是

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { 
#define _LIBCPP_END_NAMESPACE_STD } 
#define _VSTD std 

但那種失敗的目的...

回答

8

我恐怕沒有這種模擬的可能性。微軟似乎對符號版本控制非常不感興趣,儘管它們在其編譯器的每一個新版本上都在其標準庫上打破了ABI。 GCC模擬的工作原理是強大的使用是內聯命名空間功能的基礎。微軟從來沒有類似的東西,所以你不能模擬內聯命名空間。恐怕你現在暫時沒有版本化libC++。

微軟的編譯器有一個功能可能會有所幫助。這是的#pragma detect_mismatch: http://msdn.microsoft.com/en-us/library/ee956429.aspx

基本上,你把

#pragma detect_mismatch("libcxx_version", "1.0") 

到中央的libC++頭文件,每一個模塊,包括該文件將放置在它的記錄包含密鑰和值。鏈接模塊時,Microsoft鏈接器會檢查所有這些記錄對於任何給定名稱具有相同的值,並且在不匹配時提出抱怨。

最終的結果是,您不能在單個程序中擁有多個並行版本的libC++,但至少您不會在運行時鏈接導致惡意崩潰的不兼容對象文件的沉默損壞。

編輯:忘了提及:這個特性在VS2010中是新的,但是將libC++移植到沒有右值參數的編譯器中,無論如何也許是無望的。

+0

你現在領先;)。實現基本相同的結果是一種不同的方法。 – rubenvb

+0

我看到兩個可能的問題/缺點:1)這個編譯指示如何影響客戶端代碼?如何在客戶端代碼中使用此編譯指示來限制版本? 2)引入了內聯命名空間方法(我認爲)爲未來的ABI兼容性提供了一種手段,它將理想地保留舊的符號(儘管我可能會誤以爲這樣做似乎合乎邏輯)。我擔心這不足以達到這些目的,並且完全無法達到版本控制的目的。 – rubenvb

+0

1)不確定你的意思。只要密鑰不同,您可以隨意使用編譯指示。鏈接器要求所有鍵值對匹配。 –