2013-02-08 38 views
3

根據checkpatch.pl腳本「extern聲明在.c文件之外」 (用於檢查補丁是否符合編碼風格) 注意:這個在沒有編譯警告的情況下工作得很好 該問題可以通過在.h文件中放置extern聲明來解決。extern聲明爲什麼要在.c文件之外(按照linux編碼風格)

a.c 
----- 
int x; 
... 

b.c 
---- 
extern int x; 

==> checkpatch抱怨

a.h 
----- 
extern int x; 

a.c 
---- 
int x; 

b.c 
---- 
#include "a.h" 

==>不抱怨

我想知道爲什麼這是更好的

我的猜測。 理想情況下,代碼被分割成文件以模塊化代碼(每個文件都是模塊) 模塊導出的接口放置在頭文件中,以便其他模塊(或.c文件)可以包含它們。所以如果任何模塊想要在外部公開一些變量,那麼必須在對應於該模塊的頭文件中添加一個extern聲明。

同樣,具有與每個模塊(.c文件)相對應的頭文件似乎對許多頭文件具有 。

+0

這不是那麼多,因爲頭中的接口的實現可能會跨多個翻譯單元進行拆分。 – StoryTeller 2013-02-08 11:46:44

+0

*「我的Sepulation」*是正確的。而已。 – 2013-02-08 12:13:02

回答

3

將a.h包含在a.c文件中會更好。這樣編譯器就可以驗證聲明和定義是否相互匹配。

a.h 
----- 
extern int x; 

a.c 
---- 
#include "a.h" <<--- add this 
int x; 

b.c 
---- 
#include "a.h" 

該規則的原因是,正如你所假設的那樣,我們應該使用編譯器來檢查我們正在做什麼。細節更好。

如果我們允許在所有地方進行外部聲明,如果我們想要將x更改爲某種其他類型,我們會遇到麻煩。我們必須掃描多少個.c文件才能找到所有的extern int x?許多。如果我們這樣做,我們也可能會發現一些extern char x錯誤。哎呀!

只要在頭文件中有一個聲明,並在需要的地方包含它,爲我們節省了很多麻煩。在任何實際項目中,x不會是頭文件中唯一的元素,因此您不會保存文件數量。

0

我總是在.h中放置extern聲明的一個原因是爲了防止代碼複製,特別是如果使用「a.c」代碼存在或可能存在更多位代碼並且必須訪問「x」。在這種情況下,所有文件都必須具有extern聲明。

另一個原因是extern聲明是模塊的接口的一部分,因此我會將它與頭文件中的任何其他接口信息一起保存。

0

您的猜測是正確的:爲了最大化代碼重用和一致性,(公共)聲明必須放入頭文件中。

同樣,擁有與每個模塊(.c文件)相對應的頭文件似乎與許多頭文件一樣。

然後習慣它。這是一個合乎邏輯的概念,並且是一個很好的練習,可以使用

0

你有權理解extern聲明爲什麼必須放在頭文件中。所以,他們可以輕鬆地跨不同翻譯單位訪問。

此外,每個.c文件都沒有必要具有相應的.h文件。一個.h文件可以對應於相當數量的.c文件,具體取決於您的模塊隔離設計。

1

我看到兩個方面的原因:

  1. 如果您共享變量,這是因爲它不是在自己的文件,所以你想清楚地表明它是通過將extern到一個頭文件共享 - 這方式,只有一個地方[包含目錄]來搜索extern聲明。
  2. 它避免了某人作出extern聲明,然後其他人對同一事物做出不同的(如使用不同類型或屬性)extern聲明。至少如果它在[相關的]頭文件中,則所有文件都使用相同的聲明。
  3. 如果您決定更改類型,則只有兩個地方需要更改。如果您要添加也使用相同變量的「cc」文件,然後確定int不夠好,我需要long,您必須修改所有三個位置,而不是像原來那樣修改兩個位置每個「ac」,「bc」和「cc」中都包含一個頭文件。

擁有一個模塊的頭文件絕對不是一個壞主意。但它當然可以接受,具體取決於將extern放入某個現有頭文件的情況。

另一種方法是使用extern,這通常是比使用extern更好的選擇,它有一個getter function,它爲您提取變量。這樣,變量可以在其自己的源文件中是靜態的[不包含「命名空間污染」,並且變量的類型也更加明確 - 編譯器可以檢測到您是否嘗試錯誤地使用它。

編輯:我應該指出,Linux編碼風格是它出於「良好」原因的方式,但這並不意味着不屬於Linux源代碼的代碼不能破壞這些規則。各種方式。我當然不會使用Linux的格式編寫我自己的代碼 - 我喜歡在單個語句周圍額外使用{ },並且我(幾乎)總是將{放在一個新的行上,符合大括號所屬的任何內容,以及}同一列再次。

0

再一次,有一個頭文件對應於每個模塊(.c文件)似乎要很多頭文件。

正如您所說的,頭文件的想法很簡單。它們包含模塊想要導出(可用)到其他模塊(包含在其他.c文件中)的公共接口。這可以包括結構和類型以及函數聲明。現在,如果一個模塊定義了一個想要提供給其他模塊的變量,那麼將它包含在頭文件中的其他公共部分中是有意義的。這就是爲什麼extern以頭文件結尾的原因。它們只是模塊想要公開的東西的一部分。然後任何人都可以通過簡單的包含頭文件來包含這個公共接口。

每個.c文件有.h文件可能看起來很多,但它可能是正確的做法。但請記住,模塊可以在多個.c文件中實現其代碼,並選擇將其聚合公共接口導出到一個.h文件中。所以,對一件事情來說這不是一件嚴格的事情。真正的抽象是由模塊提供的公共接口。

相關問題