2011-10-27 16 views
2

當我在頭文件中混合使用靜態原型時,編譯器總是會發出嗚嗚聲。有沒有辦法在C中的同一個頭文件中有靜態原型和公共的?

說我有具有靜態原型函數一個和正常原型函數b頭main.h。然後我想要在兩個.c文件中的頭文件,即main.c和other.c。在main.c中,我需要一個包含,因爲我在任何原型之前調用該函數。

main.h:

static int a(void); 
int b(void); 

的main.c:

#include "main.h" 
void main(){ 
    a(); 
} 

static int a(void){ 
    /* do stuff */ 
} 

int b(void){ 
    /* do stuff */ 
} 

other.c:

#include "main.h" 
b(); 

什麼是最好的做法比這個分裂的明顯的解決方案頭文件轉換成專門用於靜態原型的獨立頭文件,另一個用於公共頭文件?

+0

爲什麼你需要靜態函數的頭文件呢?另外,'void main()'?如果你不是在嵌入式系統上工作,你有一些解釋要做... –

+0

@Chris我知道它應該是int。只是想盡可能使代碼小,所以我會得到一個答案:) – Pithikos

+0

我很欣賞不轉儲代碼的努力,但沒有人會被'return 0;'推遲); –

回答

4

您不要在頭文件中聲明靜態函數。由於它們是定義它們的.c文件的本地文件,因此從頭文件導出它們是沒有意義的。

有兩件事情可以做:

  1. 定義功能,它在C文件調用之前(的a()舉動定義上述主要)。
  2. 在C文件的頂部聲明靜態函數(這是我個人的選擇)。在您的情況下,您將a()的聲明移至main.c的頂部。

如果函數將用於多個翻譯單元,那麼您可以在頭文件中定義靜態函數。假設你有一個支持C99的成熟編譯器,它可以用inline代替static。

+2

3.在頭文件中定義靜態函數。在這個例子中,'a'只用於一個TU,所以它可能不應該在頭中(2是正確的)。但是,如果你實際上要在多個TU中使用'a',那麼它應該在頭文件中定義,並且假設你有一個支持C99的成熟編譯器,可以用'inline'而不是'static'。 –

+0

@SteveJessop好點。我會將其添加到答案中。 – vhallac

1

如果您在main.h中有b()的聲明,那麼爲什麼還需要在other.c中包含它呢?除此之外,這一切都很好,看不出任何問題。

要記住關於「正常」函數的重要一點是,同一函數的所有前向聲明(本例中爲b())必須匹配,否則會遇到問題(鏈接錯誤,編譯器錯誤,什麼是不)。在你的情況下,他們不匹配。

除非當然b();是對函數的實際調用,但至少在您將其超出任何範圍的代碼中,因此被視爲前向聲明。

重新編寫static前向聲明,它們限制了函數對編譯單元的可見性。因此在other.c中調用a()將不執行執行a()執行main.c。這就是C中的static的整點。

3

在頭文件中使用靜態原型沒有任何意義,原因是靜態函數具有文件範圍,所以外面的模塊都不能訪問函數。

相反,我建議你只將靜態原型放在文件頂部的.c文件中,並將它們定義在同一個文件中。

1

如果你想定義的「靜態」的功能是足夠足夠短或便宜,你會更好地把它定義爲靜態內嵌,並在* 把它的定義與它的主體(不僅是它的聲明)。頭文件h

相關問題