為什么應該用模塊取代C/C++中的頭文件?

摘要:本文整理自Apple C++工程師Doug Gregor的演講Slide,他表示希望使用模塊(Module)這一概念替代C/C++中的頭文件,現已被C++標準化委員會任命為Module研究組的主席,研究該提議的可能性。考慮到Apple的開源項目LLVM在編輯器領域中的地位,這一提議非常值得重視。

為什么應該使用模塊(Module)替代頭文件(Header)?

頭文件糟透了!


眾所周知,C程序在編譯時一般會預處理頭文件:

常規解決辦法如下:

  1. LLVM_WHY_PREFIX_UPPER_MACROS?
  2. ????LLVM_CLANG_INCLUDE_GUARD_H?
  3. ????template<class?_Tp>?
  4. ?
  5. const?_Tp&?min(const?_Tp?&__a,?
  6. ???????????????const?_Tp?&__b);?
  7. ?
  8. #include?<windows.h>?
  9. #undef?min?//?because?#define?NOMINMAX?
  10. #undef?max?//?doesn’t?

但結果依然不夠理想,比較一下代碼與程序大小你會發現:

另外,頭文件形式的可擴展性天生不足。假設有n個源文件,每個源文件引用了m個頭文件,那么構建過程的開銷會是m×n。這在C++中表現得尤為糟糕。所以預說處理頭文件是一個非常糟糕的解決方案。

C家族的模塊系統

模塊是什么?

  • 庫的接口(API)
  • 庫的實現

使用“import”導入已命名的模塊:

import會在源文件中忽略預處理狀態,并且選擇性導入,所以彈性(resilience)非常好。

使用“import”會導入什么?

  • 函數、變量、類型、模板、宏,等等;
  • 公開API——其它的都隱藏;
  • 沒有特別的命名空間機制。

C/C++引入模塊會怎么樣?


引入模塊的目標在于:

  • 在源文件中指定模塊名稱;
  • API公開;
  • 沒有頭文件!

要編寫一個模塊非常簡單,只需要使用export:

但是這么做會遇到很多遺留問題:

  • 需要遷移現在基于頭文件的類庫;
  • 與不支持模塊的編譯器的互操作性;
  • 工具需要理解模塊;

所以應該使用引入模塊的過渡方案——直接從頭文件中構建模塊。這么做有以下好處:

  • 頭文件有利于互操作;
  • 程序員不需要完全改變自己習慣的開發模式;

模塊地圖(Module Map)

模塊地圖是模塊的關鍵,用來定位模塊相關(子)模塊,包含以下功能:

  • 模塊定義命名(子)模塊

  • 頭文件在(子)模塊中包含命名頭文件的內容

保護傘頭文件(Umbrella Header)

  • 保護傘頭文件會在其目錄下包含所有頭文件信息
  • 使用通配符submodules (module *) 可以為每一個包含的頭文件創建一個子模塊:
    1. AST/Decl.h?->?ClangAST.Decl?
    2. AST/Expr.h?->?ClangAST.Expr?

模塊編譯過程:

  1. 找到命名模塊的module map;
  2. 產生一個獨立編譯器實例;
  3. 在module map中解析頭文件。

編輯模塊文件過程:

  1. 在“import”聲明處導入模塊文件;
  2. 把模塊文件保存在緩存中待重用。

從頭文件到模塊化


從頭文件編程轉換到使用模塊非常簡單:

庫方面:合并復合定義的結構、函數、宏,并且為頭文件導入依賴,最后編寫好模塊地圖;

開發者方面只需要從“#include”過渡到“import”:

  1. 把“#inlude”都換成“import”;
  2. 使用module maps確定(子)模塊(類似頭文件里的“#include”);

當然,你也可以使用工具來自動化重寫代碼,非常簡單。

工具


編輯性能

使用模塊能夠提升語法解析性能:

  • 模塊化的頭文件只需要解析一次,之后放在緩存中,于是m×n --> m+n
  • 所有基于源(source-based)工具都能帶來好處
  • 自動鏈接大大簡化了庫的使用

  • 自動導入可以阻止“#include”帶來的可怕的調試結果

調試流

通過DWARF的雙程調試有損耗:

  • 只能獲得“用過”類型和函數
  • 丟失了行內函數、模板

另外調試過程還會出現信息冗余

使用模塊的調試又會怎樣?

1.提高了構建性能

  • 編譯器發出的DWARF更少
  • 鏈接器清除重復的DWARF也更少

2.提高了調試體驗

  • 調試器的ASF精度非常完美
  • 調試器不需要尋找DWARF

總結


總而言之,C/C++使用模塊化非常有潛力:

  • 編譯/構建時間的縮短
  • 修復各種預處理問題
  • 更好的工具體驗
  • 通過設計,能夠平穩地過渡
  • Clang實現已經在進行了

這個Slide在Hacker News上引起了激烈討論,大部分網友還是贊成模塊化的方式:

baberman:對我來說沒什么不便,而且還給出了過渡方案,可能會很適合某些C/C++項目。我們應該對任何提升C/C++性能的想法持開放態度。

greggman:預處理有什么不好嗎?如果我不想用預處理,我完全可以使用Objective-C等。現在的機器性能已經夠強大了,import在編譯上的性能優勢對我來說沒有任何吸引力,我更喜歡C/C++的傳統方式。

msbarnett反駁greggman:我認為這正是這份提議的精髓所在,你既可以保留使用#include,也可以從現在開始就轉向import模塊的方式。

_djo_:這個想法會非常有前途!要說缺點的話就是來得太遲了!

nkurz:我不同意“m個頭文件+n個源文件 --> m×n倍編譯性能”。只要使用“#ifndef _HEADER_H”就不會出現這個問題,或者,為什么不使用#include_once <header.h>來解決呢?預處理很可怕嗎?預處理確實有一些問題,但是卻是可以克服的。

SeoxyS:我不關心性能,現在性能已經不是問題了,我更關心怎樣給開發者更少的負擔。

各位CSDN網友是怎樣看的呢?歡迎一起討論。

相關鏈接:Doug的Slide、Hacker News上的討論

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/449725.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/449725.shtml
英文地址,請注明出處:http://en.pswp.cn/news/449725.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

北向資金進行股票、期貨指數、基金策略

#%%導入包 import tushare as ts import datetime import pandas as pd import numpy as np import akshare as ak import warnings warnings.filterwarnings("ignore")#獲取北向資金數據 df_data2 ak.stock_em_hsgt_north_acc_flow_in(indicator"北上") d…

Kong Api 初體驗、Kong安裝教程

見&#xff1a;https://blog.csdn.net/forezp/article/details/79383631Kong是一個可擴展的開源API層&#xff08;也稱為API網關或API中間件&#xff09;。 Kong運行在任何RESTful API的前面&#xff0c;并通過插件擴展&#xff0c;它們提供超出核心平臺的額外功能和服務。 Kon…

Spring Boot2.0+中,自定義配置類擴展springMVC的功能

在spring boot1.0&#xff0c;我們可以使用WebMvcConfigurerAdapter來擴展springMVC的功能&#xff0c;其中自定義的攔截器并不會攔截靜態資源&#xff08;js、css等&#xff09;。 Configuration public class MyMvcConfig extends WebMvcConfigurerAdapter {Overridepublic v…

從谷歌宕機事件認識互聯網工作原理

摘要&#xff1a;谷歌服務器經歷了短暫的宕機事件&#xff0c;持續大概27分鐘&#xff0c;對部分地區的互聯網用戶造成了影響。此次事件的原因深究起來需要進入互聯網絡那深邃的、黑暗的角落。 譯者注&#xff1a;本文中提到CloudFlare是一家總部位于美國舊金山的內容分發網絡(…

聊聊技術寫作的個人體會

有群友問過&#xff0c;是什么原因使我開始寫技術公眾號&#xff0c;又是什么動力讓我堅持寫的。 在我看來&#xff0c;寫作是一件不能敷衍的事&#xff0c;通過寫作來學習&#xff0c;反而要比單純地學習的效果要好。為了寫成一篇“拿得出手”的文章&#xff0c;我要反復查找資…

「2019冬令營提高組」全連

傳送門 顯然的 $dp$ 設 $f[i]$ 表示點擊第 $i$ 個音符時的最大價值&#xff0c;$t[i]$ 表示音符 $i$ 的準備時間 那么可以枚舉 $1$ 到 $i-t[i]$ 的所有音符&#xff0c;如果 $j$ &#xff0c;如果 $jt[j]$ 小于等于 $i$ &#xff0c;那么 $f[i]max(f[i],f[j]t[i]*val[i])$ 考慮…

Docker常用命令、超實用、講解清晰明了(rm、stop、start、kill、logs、diff、top、cp、restart ...)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 查看docker信息&#xff08;version、info&#xff09; # 查看docker版本 $docker version # 顯示docker系統的信息 $docker i…

推薦給開發人員的實用命令行工具

摘要&#xff1a;優秀的工具對于定位問題出在何處有著無可估量的價值&#xff0c;而且能在一開始就幫助我們阻止問題的出現&#xff0c;總的來說能使我們的工作更有效率。本文介紹了6個非常強大且靈活的工具&#xff0c;熟練使用這些工具能使你的生活變得更輕松一些。 作為一名…

雷軍:啟動手機+AIoT雙引擎戰略 5G春天到來前打持久戰

雷帝網 樂天 1月11日報道 小米CEO雷軍今日在小米年會上宣布&#xff0c;2019年&#xff0c;小米將正式啟動“手機AIoT”雙引擎戰略&#xff0c;這將是小米未來五年的核心戰略。未來5年&#xff0c;小米將在AIoT領域持續投入超過100億元。從2019年起&#xff0c;AIoT&#xff0c…

Jenkins自定義主題

x下載自定義樣式 http://afonsof.com/jenkins-material-theme/ 打開連接 最后點擊&#xff1a;DOWNLOAD TOUR THEME! 得到樣式文件&#xff1a;jenkins-material-theme.css 上傳樣式文件到jenkins 將jenkins-material-theme.css 上傳到&#xff1a; /var/jenkins_home/userCont…

SSH (Secure Shell)詳解

Secure Shell&#xff08;SSH&#xff09;是一種加密 網絡協議&#xff0c;用于在不安全的網絡上安全地運行網絡服務。 SSH通過客戶端 - 服務器體系結構中的不安全網絡提供安全通道&#xff0c;將SSH客戶端應用程序與SSH服務器相連接。 常見的應用程序包括遠程命令行登錄和遠程…

股票配對收益

import pandas as pd import numpy as npimport matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 字體設置 import matplotlib matplotlib.rcParams[axes.unicode_minus]False # 負號顯示問題from arch.unitroot import ADF …

YUV420、YUV422、RGB24轉換

//平面YUV422轉平面RGB24 static void YUV422p_to_RGB24(unsigned char *yuv422[3], unsigned char *rgb24, int width, int height) { int R,G,B,Y,U,V; int x,y; int nWidth width>>1; //色度信號寬度 for (y0;y<height;y) { for (x0;x<width;x) { …

最長非下降子序列(O(nlogn))(offer收割)

題目 如題 思路 核心思想是&#xff0c;維護一個數組ends&#xff0c;它記錄了長度為k的子序列的末尾元素的最小值。聽起來很抽象&#xff0c;我們不妨手動演示一遍整個過程。 假設數組a{2,9,4,27,29,15,7}&#xff0c;令length表示當前找到的最長非下降子序列的長度。初始時le…

[Python]小甲魚Python視頻第026課(字典:當索引不好用時2)課后題及參考解答

# -*- coding: utf-8 -*- """ Created on Fri Mar 8 10:32:20 2019author: Administrator """"""測試題&#xff1a;0. Python的字典是否支持一鍵&#xff08;Key&#xff09;多值&#xff08;Value&#xff09;&#xff1f;不支…

2021-08-12 畫蠟燭線

畫蠟燭線 pip install https://github.com/matplotlib/mpl_finance/archive/master.zip from mpl_finance import candlestick_ochl import matplotlib.pyplot as plt from matplotlib.pylab import date2num# 先畫日K線 fig, axes plt.subplots(nrows1, ncols1, figsize(20, …

替換字符串列表中字符串

//替換字符串列表中字符串 procedure StringsReplace(var S : TStrings; OldPattern, NewPattern: string; Flags: TReplaceFlags);var i : integer; tmpstr : string;begin for i : 0 to S.Count -1 do begin tmpstr : S[i]; s[i] : StringReplace(tmpstr, Ol…

TCP/IP協議族 詳解(TCP/IP四層模型、OSI七層模型)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 TCP/IP協議族&#xff08;TCP/IP Protocol Suite&#xff0c;或TCP/IP Protocols&#xff09;&#xff0c;簡稱TCP/IP。由于在網絡通訊協…

RGB 24和YUY2相互轉換

YUY2經常用于電視制式以及許多攝像頭的輸出格式.而我們在處理時經常需要將其轉化為RGB進行處理,這里簡單介紹下YUY2(YUV)與RGB之間相互轉化的關系: http://msdn2.microsoft.com/en-us/library/ms893078.aspx YUY2(YUV) To RGB: C Y - 16 D U - 128 E V - 128 R clip((…

通達信獲取數據

#python第三方庫pytdx獲取 from pytdx.hq import TdxHq_API api TdxHq_API() # 數據獲取接口一般返回list結構&#xff0c;如果需要轉化為pandas Dataframe接口&#xff0c;可以使用 api.to_df 進行轉化 with api.connect(119.147.212.81, 7709): # 返回普通list data …