2016-01-07 65 views
42

已經有支持C++模塊兩種編譯器:我應該如何編寫我的C++來爲C++模塊做準備?

當現在開始一個新項目,我應該怎麼注意,爲了當它最終在我的編譯器中發佈時能夠採用模塊功能?

是否可以使用模塊,並仍然保持與不支持它的較舊編譯器的兼容性?

+3

我有點膽怯地給一個擁有超過2400個信譽點的人提供答案...... ^^我問自己是否真的很重要在每次發佈C++的新升級以將我的所有代碼更改爲新功能時寫入?這會導致很多副作用或體系結構的變化......如果我是你,我會編寫自己的元語言,這種語言將會不變(或者我有更多的控制權),並且我會寫一個函數來傳遞我的語言在我的選擇的任何其他本地編程語言。這就像是硬件虛擬化的想法。 –

+2

@NECIPS SO是一個知識庫,你不回答我,而是「回到世界」。如果有人親自問我這個問題,我會說「去寫一個測試項目,玩它並自己找出來」。幾年前,有人會這樣做,並寫一篇關於它的博客文章。現在我希望有人會寫一個SO回答。 – user7610

+0

也許「Waldo」可以回答你的問題(http://theres-waldo.ca/2014/07/17/trip-report-c-standards-committee-meeting-in-rapperswil-june-2014/) –

回答

19

已經有支持C++模塊

鐺兩種編譯器:http://clang.llvm.org/docs/Modules.html MS VS 2015年:http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1.aspx

微軟的做法似乎是一個獲得最牽引,主要是因爲微軟在其實施比目前鐺民間扔了很多更多的資源。有關我的意思,請參閱https://llvm.org/bugs/buglist.cgi?list_id=100798&query_format=advanced&component=Modules&product=clang,在Modules for C++中有一些較大的showstopper錯誤,而針對C或尤其是Objective C的模塊在現實世界的代碼中看起來更有用。 Visual Studio最大也是最重要的客戶微軟正在爲模塊努力工作,因爲它解決了大量的內部構建可伸縮性問題,而微軟的內部代碼是一些最難編譯的C++,因此你不能拋出任何編譯器除了MSVC以外(例如,運氣好的話可以使用clang或GCC來編譯40k行代碼)。因此,Google等使用的鐺聲構建技巧不適用於微軟,他們迫切需要儘快修復而不是稍後修復。

這並不是說Microsoft的建議在實踐中應用於大型真實世界的代碼庫時並沒有一些嚴重的設計缺陷。不過,Gaby認爲你應該重構你的代碼,雖然我不同意,但我可以看到他來自哪裏。

現在開始一個新項目時,爲了能夠在我的編譯器中最終發佈時採用模塊功能,我應該注意些什麼?

,只要微軟的編譯器目前預期實現的模塊,你應該確保你的庫是可用在所有這些形式:

  1. 動態庫
  2. 靜態庫
  3. 僅頭文件庫

許多人非常驚訝的是,C++ Modules目前預計會是imp lemented保留了這些區別,所以現在你得到了一個C++模塊變體以上所有三個,第一個看起來像人們期望C++模塊是最後看起來最後看起來最像一個更有用的預編譯頭。您應該支持這些變體的原因是您可以重複使用大部分相同的預處理器機器,以支持C++模塊而只需很少的額外工作。

稍後,Visual Studio將允許將模塊定義文件(.ifc文件)作爲資源鏈接到DLL中。這將最終消除對MSVC上.lib和.dll區分的需求,您只需向編譯器提供一個DLL,並且它在模塊導入,「沒有標題」或任何其他需要的情況下都「正常工作」。這當然聞起來有點像COM,但沒有COM的大多數好處。

是否有可能使用的模塊在一個單一的代碼庫,並仍然保持與不支持舊的編譯器兼容?

我打算假設你的意思是上面插入的粗體文本。

答案通常是肯定的,即使更多的預處理器宏的樂趣。 #include <someheader>可以變成頭部內的import someheader,因爲預處理器仍然照常工作。因此,您可以標記單個庫頭與C++模塊支持沿東西這樣的詩句:

// someheader.hpp 

#if MODULES_ENABLED 
# ifndef EXPORTING_MODULE 
import someheader; // Bring in the precompiled module from the database 
// Do NOT set NEED_DEFINE so this include exits out doing nothing more 
# else 
// We are at the generating the module stage, so mark up the namespace for export 
# define SOMEHEADER_DECL export 
# define NEED_DEFINE 
# endif 
#else 
// Modules are not turned on, so declare everything inline as per the old way 
# define SOMEHEADER_DECL 
# define NEED_DEFINE 
#endif 

#ifdef NEED_DEFINE 
SOMEHEADER_DECL namespace someheader 
{ 
    // usual classes and decls here 
} 
#endif 
在你的main.cpp或任何

現在,你只需要做:

#include "someheader.hpp" 

...如果編譯器有/ experimental:modules/DMODULES_ENABLED,那麼你的應用程序會自動使用你的庫的C++ Modules版本。如果沒有,就像我們一直所做的那樣,你會得到內聯包含。

我認爲這些是您的源代碼的最小可能的一系列更改,使您的代碼模塊現在就緒。你會注意到我沒有提到構建系統,這是因爲我仍在調試我編寫的cmake工具,以使所有這些東西能夠「無縫地工作」,並且我希望能夠在幾個月內調試它。期待在明年或者之後的C++會議上看到它:)

2

是否可以使用模塊並仍然保持與不支持它的舊編譯器的兼容性?

不,這是不可能的。它可能使用一些魔法#ifdef這樣纔有可能:

#ifdef CXX17_MODULES 
    ... 
#else 
    #pragma once, #include "..." etc. 
#endif 

但這意味着你仍然需要提供.h支持,從而失去所有優點,再加上你的代碼現在看起來很醜陋。

如果你想採用這種做法,最簡單的方法來檢測「CXX17_MODULES」我只是做了是編譯使用模塊,您所選擇的構建系統一個小的測試程序,並定義一個全局爲大家看看是否編譯成功。

現在開始一個新項目時,爲了能夠在我的編譯器中最終發佈時採用模塊功能,我應該注意些什麼?

這取決於。如果你的項目是企業,並且讓你吃到盤子裏的食物,那麼一旦它在馬廄裏得到釋放,它會變得廣泛適應。另一方面,如果你的項目可以承擔起流血事件,無論如何都要使用模塊。

基本上,它與Python3和Python2,或不太相關的PHP7和PHP5是一樣的故事。你需要找到是一個很好的跟上時代的程序員,而不是討厭的人在兩者之間取得平衡的Debian ;-)

+1

爲什麼downvote?無論如何,C++模塊還不是另一個瘋狂的ubercool功能,如用戶定義的文字,而是深思熟慮的解決實際問題的解決方案(用C++代碼表示模塊化)。如果我的代碼設計得很好,它已經是模塊化的。我只需要將它傳達給工具,以便它可以利用它, – user7610

+0

我同意我們必須等待一段時間才能使用它。我說2025它將是非標準使用。甲骨文,IBM和英特爾開發緩慢的編譯器將成爲主要問題。 Oracle仍然是C++ 11 – Lothar

相關問題