2013-08-02 27 views
0

有人可以向我解釋這個嗎?鏈接器說未定義的函數參考

的文件如下:

file a.c 
#include <stdio.h> 
#include <stdlib.h> 

int fun1(); 
int main() 
{ 
    fun1(); 
    return 0; 
} 

文件B被寫爲:

file b.c 
static int fun1(); 
int fun1(){ 
    printf("fron fun1"); 
    return 0; 
} 

當我嘗試編譯我的代碼,編譯器提供了一個錯誤:未定義的引用FUN1。 如果我在文件b.c中聲明fun1 static,這意味着什麼?

+3

'static'表示函數的作用域限於你聲明的模塊(文件)。所以你需要刪除文件'b.c'中的'static'聲明。通過'b.c'中的'static'聲明,'a.c'不能訪問'fun1'。 – lurker

+1

您確定這是一個編譯器錯誤而不是鏈接器錯誤? – Dabbler

+0

請發佈您用於編譯的命令行。 @Dabbler表示,您可能正在查看鏈接器錯誤。 –

回答

3

如果您在b.c中聲明fun1static,它將不會在外部可見,所以您只能在編譯單元b.c中使用它。丟掉static

注意:爲了能夠編譯你的代碼,你還需要在b.c的頂部添加#include <stdio.h>

+0

你有試過嗎?它仍然會導致編譯器錯誤。 –

+0

那麼''printf'不是'b.c'中導入的,但那不是問題。 – flyx

+0

它導致鏈接器錯誤,而不是編譯器錯誤。 – stev

0

使用externa.cextern int fun1();

注:fun1()在默認情況下外部鏈接。

,並刪除static int fun1();b.c

編譯使用:

gcc -o test a.c b.c

+0

'extern'是可選的,對彙編影響不大。 – flyx

+0

@flyx ouhh是的,只是爲了可讀性,我不應該,雖然,謝謝 – P0W

+0

可讀性是一件好事,值得一提。說到可讀性,我更喜歡頭文件到實現文件中的外部聲明。 – flyx

0

好,你問這個問題的文件b.c英寸

當你聲明的東西static像一個函數,該函數只有在它已經宣佈,換句話說,你有b.c的功能,只有存在,因此可以在b.c使用相同翻譯單元是可見的。

所以你連接正在考慮中b.c不作爲選項功能,這給你留下一個未定義的引用,因爲在此代碼中沒有其他的實現是能夠解決這個符號。

0

編譯器錯誤的原因: 在文件「a.c」中沒有函數fun1()的定義。

解決方案1:

declare fun1() as extern in "a.c" : extern int fun1(); 

解決方案2:

Add #include "b.c" in "a.c" 
0

static功能,你只定義了在該文件中,即它是局部的翻譯單元是可見的。

這就是編譯器(鏈接器)無法找到該函數定義的原因。 刪除靜態關鍵字。

對於編譯,只有函數原型就足夠了,但在鏈接時,必須確保聲明在編譯期間存在的函數確實存在於其他一些文件中。但通過將其聲明爲static,您將該函數的定義限制爲只有該文件,並且不會使需要(調用)該文件的文件可見。