日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

为什么应该用模块取代C/C++中的头文件?

發布時間:2023/12/18 c/c++ 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么应该用模块取代C/C++中的头文件? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
摘要:本文整理自Apple C++工程師Doug Gregor的演講Slide,他表示希望使用模塊(Module)這一概念替代C/C++中的頭文件,現已被C++標準化委員會任命為Module研究組的主席,研究該提議的可能性。考慮到Apple的開源項目LLVM在編輯器領域中的地位,這一提議非常值得重視。

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

頭文件糟透了!


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

常規解決辦法如下:

  • LLVM_WHY_PREFIX_UPPER_MACROS?
  • ????LLVM_CLANG_INCLUDE_GUARD_H?
  • ????template<class?_Tp>?
  • ?
  • const?_Tp&?min(const?_Tp?&__a,?
  • ???????????????const?_Tp?&__b);?
  • ?
  • #include?<windows.h>?
  • #undef?min?//?because?#define?NOMINMAX?
  • #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 *) 可以為每一個包含的頭文件創建一個子模塊:
    • AST/Decl.h?->?ClangAST.Decl?
    • AST/Expr.h?->?ClangAST.Expr?

    模塊編譯過程:

  • 找到命名模塊的module map;
  • 產生一個獨立編譯器實例;
  • 在module map中解析頭文件。
  • 編輯模塊文件過程:

  • 在“import”聲明處導入模塊文件;
  • 把模塊文件保存在緩存中待重用。
  • 從頭文件到模塊化


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

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

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

  • 把“#inlude”都換成“import”;
  • 使用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上的討論

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的为什么应该用模块取代C/C++中的头文件?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。