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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

生成的包含卫兵:一次替代实用主义

發(fā)布時間:2024/3/13 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 生成的包含卫兵:一次替代实用主义 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
照片由Toa Heftiba在Unsplash上拍攝

介紹

在C ++中,沒有什么可以阻止程序員多次包含頭文件。 這可能會導(dǎo)致定義重復(fù),這是一個錯誤。 由于很難確保只將頭文件包含一次,因此常見的策略是僅對第一個包含計數(shù)進(jìn)行計數(shù)。 可以使用“包含保護(hù)”來完成,這是一小段預(yù)處理器邏輯,如下所示:

它是如何工作的?

在第一個include上, HEADER_HAS_BEEN_INCLUDED未定義,因此我們定義foo 。 在隨后的包含中,已定義HEADER_HAS_BEEN_INCLUDED ,因此我們僅跳過內(nèi)容。

例如,如果我們有此C ++文件:

然后它將擴(kuò)展為:

在預(yù)處理程序完成后,我們將得到以下結(jié)果:

這是慣用的方法,但是有一些限制:

  • 需要三行樣板代碼
  • 第1行和第2行的變量名稱必須完全匹配
  • 相同的變量名不能在多個文件中使用
  • 我們必須記住#endif ,它位于文件#ifndef的另一端
  • 那一次實(shí)用主義呢?

    #pragma once旨在克服這些問題。 它是C ++編譯器的非標(biāo)準(zhǔn)功能,但得到了廣泛支持。 這個概念很簡單:任何包含#pragma once文件實(shí)際上只會被包含一次,即使程序員多次包含它。

    #pragma once使用#pragma once ,我們的示例變?yōu)?#xff1a;

    看起來不錯吧? 可悲的是, #pragma once帶來了許多問題。

    根本原因是#pragma once涉及其中一些代碼的生活,而不是它的內(nèi)容 。 如果您可以通過多個路徑訪問同一文件的兩個副本,那么它將被包含兩次。 而且,如果您有兩條路徑看起來不同但實(shí)際上相同,那么編譯器可能不會發(fā)現(xiàn)這一點(diǎn)。 最重要的是,它不是標(biāo)準(zhǔn)的,因此編譯器實(shí)現(xiàn)不必尊重其語義。

    可能的解決方法

    #pragma once的問題#pragma once源于它在文件的位置而不是其內(nèi)容上起作用的事實(shí)。 如果我們只是使用內(nèi)容呢? (當(dāng)然,記錄每個標(biāo)題的所有內(nèi)容會很慢,但是我們可以通過記錄內(nèi)容的哈希值來進(jìn)行優(yōu)化)。

    該過程將是:

    1.包含頭文件時,對其進(jìn)行哈希處理
    2.如果以前已經(jīng)看到過哈希,則忽略包含
    3.否則,正常包含標(biāo)題

    這將是一個可靠的解決方案,因?yàn)樗静魂P(guān)心文件所在的路徑,而只關(guān)心文件的內(nèi)容。

    實(shí)施解決方法

    將新命令添加到C ++標(biāo)準(zhǔn)將花費(fèi)大量時間,但是幸運(yùn)的是,我們可以使用腳本和預(yù)處理器來實(shí)現(xiàn)此邏輯。

    基本思想是這樣的:

    因此,例如此標(biāo)頭:

    SHA-256哈希值為:

    因此,生成的標(biāo)頭可能是:

    盡管單個文件的轉(zhuǎn)換很簡單( Python腳本 ),但我們?nèi)匀恍枰芾磙D(zhuǎn)換過程。 我們需要確保:

    • 為每個文件運(yùn)行轉(zhuǎn)換
    • 新文件將自動轉(zhuǎn)換
    • 刪除文件的轉(zhuǎn)換會自動刪除
    • 僅在文件更改后才重新運(yùn)行轉(zhuǎn)換
    • 獎勵:轉(zhuǎn)換可以安全地放入共享的網(wǎng)絡(luò)緩存中

    使用Buck build ,我們可以輕松地將此邏輯編碼到項目的構(gòu)建腳本中。

    讓我們從單個文件的構(gòu)建規(guī)則開始,然后進(jìn)行概括:

    Buck中的genrule很像Make中的目標(biāo)。 我們定義輸入文件,輸出文件名和要執(zhí)行的命令。 該目標(biāo)使用我們的Python腳本來生成包含保護(hù),并在add.hpp上運(yùn)行它。 與Make不同,Buck將在輸入哈希中隔離并緩存該進(jìn)程。

    現(xiàn)在我們只有一個文件,我們可以將流程推廣到n文件。 為此,我們制作了一個Python函數(shù),該genrule為給定的文件創(chuàng)建了一個genrule :

    要獲取頭文件集,我們運(yùn)行一個glob表達(dá)式。 例如:

    并將所有內(nèi)容整合在一起:

    您可以在GitHub上找到完整的工作示例 。

    現(xiàn)在,我們的頭文件可以一次編寫而無需包含保護(hù)或#pragma once :

    Buck中的此設(shè)置非常適合與以下對象一起使用:

    • 頭文件中的零樣板
    • Buck會自動檢查新的頭文件,因此構(gòu)建始終是最新的
    • Buck將刪除過時的頭文件
    • 因?yàn)樗私饽繕?biāo)圖,所以Buck將并行生成標(biāo)頭
    • Buck將緩存生成的頭,以便僅在需要時才計算
    • 我們不再依賴人類的準(zhǔn)確性(包括防護(hù)措施)或非標(biāo)準(zhǔn)功能( #pragma once )

    既然你在這里...

    我們創(chuàng)建了Buckaroo ,以便更輕松地集成C ++庫。 如果您想嘗試一下,最好的起點(diǎn)是文檔 。 您可以瀏覽Buckaroo.pm上的現(xiàn)有軟件包,或在愿望清單上請求更多。

    C ++依賴管理的方法,或者為什么我們構(gòu)建Buckaroo
    C ++是一種不常見的語言,因?yàn)樗€沒有主要的程序包管理器(我們正在努力!)。 結(jié)果是…… hackernoon.com

    From: https://hackernoon.com/generated-include-guards-an-alternative-to-pragma-once-31cc3dee6ce

    總結(jié)

    以上是生活随笔為你收集整理的生成的包含卫兵:一次替代实用主义的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。