簡體   English   中英

以這種方式包含 header 文件,這是一個好習慣嗎?

[英]include header file in this way, is this a good practice?

在 gumbo html 解析器源代碼中,我看到了一些像這樣的#include的奇怪用例。 它們只是在數組定義塊中包含 header 文件。

const char* kGumboTagNames[] = {
#include "tag_strings.h"
    "",  // TAG_UNKNOWN
    "",  // TAG_LAST
};

static const unsigned char kGumboTagSizes[] = {
#include "tag_sizes.h"
    0,  // TAG_UNKNOWN
    0,  // TAG_LAST
};

然后在tag_string.h文件中列出所有合法的 html 標簽,

"html",
"head",
"title",
"base",
"link",
"meta",
"style",
"script",
"noscript",
...
...

我知道它有效,但仍然想知道這是導入外部數據的傳統方式,還是只是一種不尋常的破解方式?

如果您包含的數組內容是由其他進程自動生成的,那么這是使用#include的一種不錯且有點傳統的方式。 (不過,還有其他方法可以做到這一點,正如我將在下面提到的那樣。)

這是一個經典的權衡。 大多數時候,一個值得遵循的好規則是您應該以直接、傳統的方式使用預處理器,因為當您開始變得“棘手”時,很容易造成一團糟。

但有時,您有一個數組,您真的想使用一些自動的外部過程生成其內容。 將數組定義復制並粘貼到您的源文件中既乏味又容易出錯,並且您可能不得不不斷重做,因為數組需要更新。 找出一種自動化該過程的方法是值得做的,甚至可能值得違反“沒有棘手的預處理器濫用”規則。

為了完成這項工作,您通常需要一些自動過程(可能是 awk、sed、perl 或 python 腳本)來生成具有正確語法的包含文件。 如果您正在使用make或類似的東西,您可以在數組的實際源數據發生變化時自動執行該步驟。 例如,在您給出的示例中,您可能有一個原始的“源文件” tags.list包含如下行

html
head
title

然后在您的 Makefile 中使用類似sed 's/.*/"&",'來創建具有正確字符串初始值設定項語法的包含文件。 這樣您就不會強迫更新列表的人記住始終使用正確的引號和逗號。

此外,正如其他評論員所建議的那樣,您可能應該給文件一個以.h以外的其他名稱結尾的名稱,以表明它不是包含完整、有效的 C 聲明的普通 header 文件。 在這種情況下更好的可能性是.tab.inc.arr

不過,只要多做一點工作,您就可以避免“hack”並以大約 100% 的常規方式做事。 如果您調整腳本以在生成的文件的開頭添加行const char* kGumboTagNames[] = {}; 最后,您可以給它一個以.c結尾的名稱,然后只編譯它,而不是包含它。 (但是,這種方法會涉及其自身的權衡,因為它將數組限制為全局數組,而不是 static 或本地數組。)

腳注:在某些語言中——甚至在 C 和 C++ 中,在某些情況下——逗號用作分隔符,並且不允許在列表的最后一個元素之后使用逗號。 但是在數組初始值設定項中,你可以有那個尾隨逗號,事實證明這是一個非常好的和有用的自由,正是因為它允許你使用像這里描述的那樣簡單的技術,而不必插入一個令人討厭的明確的額外步驟以刪除列表中最后一個元素之后的逗號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM