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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

介紹

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

它是如何工作的?

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

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

然后它將擴展為:

在預處理程序完成后,我們將得到以下結果:

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

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

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

    #pragma once使用#pragma once ,我們的示例變為:

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

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

    可能的解決方法

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

    該過程將是:

    1.包含頭文件時,對其進行哈希處理
    2.如果以前已經看到過哈希,則忽略包含
    3.否則,正常包含標題

    這將是一個可靠的解決方案,因為它根本不關心文件所在的路徑,而只關心文件的內容。

    實施解決方法

    將新命令添加到C ++標準將花費大量時間,但是幸運的是,我們可以使用腳本和預處理器來實現此邏輯。

    基本思想是這樣的:

    因此,例如此標頭:

    SHA-256哈希值為:

    因此,生成的標頭可能是:

    盡管單個文件的轉換很簡單( Python腳本 ),但我們仍然需要管理轉換過程。 我們需要確保:

    • 為每個文件運行轉換
    • 新文件將自動轉換
    • 刪除文件的轉換會自動刪除
    • 僅在文件更改后才重新運行轉換
    • 獎勵:轉換可以安全地放入共享的網絡緩存中

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

    讓我們從單個文件的構建規則開始,然后進行概括:

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

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

    要獲取頭文件集,我們運行一個glob表達式。 例如:

    并將所有內容整合在一起:

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

    現在,我們的頭文件可以一次編寫而無需包含保護或#pragma once :

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

    • 頭文件中的零樣板
    • Buck會自動檢查新的頭文件,因此構建始終是最新的
    • Buck將刪除過時的頭文件
    • 因為它了解目標圖,所以Buck將并行生成標頭
    • Buck將緩存生成的頭,以便僅在需要時才計算
    • 我們不再依賴人類的準確性(包括防護措施)或非標準功能( #pragma once )

    既然你在這里...

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

    C ++依賴管理的方法,或者為什么我們構建Buckaroo
    C ++是一種不常見的語言,因為它還沒有主要的程序包管理器(我們正在努力!)。 結果是…… hackernoon.com

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

    總結

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

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