如果main.c
和test.c
是單獨的翻譯單元,那麼您應該是正確的。但是,通過將test.c
的文本直接包含到main.c
中,您創建了一個單個轉換單元,因此對於main
可以看到靜態函數。它的行爲好像你已經將它全部寫入一個文件一樣。
你不想#include
包含變量或函數的文件定義;這是在編譯或鏈接時遇到多個定義錯誤的好方法。相反,#include
文件的內容應限於類型定義,非定義變量聲明和函數聲明。
如下您可以創建一個文件test.h
:
#ifndef TEST_H // include guard; prevents this file from being processed
#define TEST_H // more than once per translation unit
void foo(); // declaration for foo; this is the only function we're exposing
#endif
然後重寫main.c
作爲
#include "test.h"
int main(void)
{
test();
return 0;
}
你會再編譯main.c
和test.c
分開,然後鏈接生成的目標文件來創建可執行文件:
gcc -c main.c
gcc -c test.c
gcc -o test main.o test.o
此時您將沿着「未定義參考」的順序收到鏈接器錯誤,因爲test
的符號尚未導出。
是的,這是因爲包括。您應該只包含頭文件'.h'。 – jweyrich
@jweyrich:真的嗎?預處理器對符號一無所知,它只是解析由chars組成的令牌。你能否解釋一下#include一個c文件與直接粘貼它的內容有什麼不同? –
@flix請嘗試僅包含* .h文件而非* .c文件。 – Allwyn